对于循环 - 条件破坏 - 内部的异步函数

时间:2017-04-17 05:49:17

标签: javascript for-loop asynchronous

有人可以向我解释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
*/

2 个答案:

答案 0 :(得分:2)

您的循环正好执行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++){

答案 1 :(得分:1)

Maximus告诉您为什么代码正在执行它的功能。但你怎么解决它?最基本的方法,如果您可以使用ES6语言功能(您可能可以,因为看起来您正在使用Node.js),则使用let而不是var声明变量。 let表现得像你可能期望的那样。除了从lambdas引用时表现得更合理,使用let声明的变量是块作用域而不是函数作用域,这更直观。