【问题标题】:For loop - condition breaking - async function insideFor循环 - 条件破坏 - 里面的异步函数
【发布时间】:2017-04-17 05:49:17
【问题描述】:

有人可以向我解释这里的for 循环发生了什么吗?我不明白为什么循环超出了它的条件。我希望条件[i] 停止在'2'。我想这种行为对于for 循环中的其他异步函数是相同的。非常感谢!

var path = require('path')
var fs = require('fs')
var request = require('request')
var cheerio = require('cheerio')

for (i=0; i < 3; i++) {
    console.log(i)
    var arr = []
    var url = 'https://en.wikipedia.org/wiki/Web_scraping'

    request (url, function(error,response,body) {
      if(error){
        throw err;
      } $ = cheerio.load(body)

      var x = $.html()
      console.log(i)
    })
}

/* Results
0
1
2
3
3
3
*/

【问题讨论】:

  • 试运行此条件for(i=0; i &lt; 3; i++){,如果它从0 开始,它将运行3 次,只运行两次更改for(i=1; i &lt; 3; i++){for(i=0; i &lt; 2; i++){for(i=0; i &lt;= 1; i++){

标签: javascript for-loop asynchronous


【解决方案1】:

您的循环恰好执行了 3 次,并在此处记录 i - 0,1,2

for(i=0; i < 3; i++){
    console.log(i)
    ^^^^^^^^^^^^^  <--------------------------------

然后这里添加的回调

request(url, function(error,response,body){
             ^^^^^^^^^^^^ <----------------------------

执行3次并记录3, 3, 3:

    if(error){
        throw err;
    } $ = cheerio.load(body)
        var x = $.html()
        console.log(i)
        ^^^^^^^^^^^^^ <-----------------------------
    })

请参阅 this question 以了解为什么 i 在回调中输出为 3 三次,而不是您可能期望的 0, 1, 2。如果你使用let 而不是var,你会得到0, 1, 2

for(let i=0; i < 3; i++){

【讨论】:

  • 感谢 Maximus 将其分解。实际上,我不希望函数返回“0,1,2”,因为我知道“i”条件在异步返回任何值时已经达到其最大值。我希望“2、2、2”。如果它循环执行 3 次,而不是 4 次,那么为什么会有 "3" ?感谢您的链接。我现在就过一遍!
  • @user7861743,不客气。 我希望“2、2、2”,不,当循环结束时,i 计数器是 3...这就是为什么 i &lt; 3 条件计算为 false 和循环结束。否则,如果i 停留在2,则循环将永远不会结束。顺便说一句,如果有帮助,你可以接受我的回答
【解决方案2】:

Maximus 会告诉您代码为何如此运作。但是你如何解决它?如果您可以使用 ES6 语言功能(您可能可以,因为看起来您使用的是 Node.js),最基本的方法是使用 let 而不是 var 声明您的变量。 let 的行为方式可能符合您的预期。除了在从 lambda 引用时表现得更合理之外,使用 let 声明的变量是块作用域而不是函数作用域,这更直观。

【讨论】:

  • 感谢布赖恩的解释。我正在使用自动执行功能来解决我面临的问题,但我尝试了“让”,似乎输出完全相同。
猜你喜欢
  • 2020-09-07
  • 2019-04-07
  • 2014-07-09
  • 1970-01-01
  • 1970-01-01
  • 2018-09-24
  • 2015-11-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多