Node.js - 循环异步

时间:2016-12-07 19:09:29

标签: javascript mysql node.js loops

我是nodejs的新手并尝试在for循环中调用一个函数来打印一些东西。

var mysql = require("mysql"),
    async = require("async");

function test() {

    setTimeout(function () {
      console.log('boo');
    }, 100)
}

con.query('SELECT * FROM database', function(err, rows){
    if(err) throw err;

    for (var i = 0; i < rows.length; i++) {
        console.log('Processing ID: ' + rows[i].id);
        test();
    }

});

似乎循环不等待boo似乎继续通过所有值。这是输出:

Processing ID: 1
Processing ID: 2
boo
boo

但我真正想要的是:

Processing ID: 1
boo
Processing ID: 2 
boo

我也尝试使用这样的异步库:

async.each(rows, function(rows, callback) {         
    console.log('Processing ID: ' + rows.id);
    test();
    callback();

}, function(err) {
    if( err ) {
        console.log('A file failed to process');
    } else {
        console.log('All files have been processed successfully');
    }
});

2 个答案:

答案 0 :(得分:0)

setTimeout是异步的,不会阻止其余的代码。它主要是说“我将在100毫秒内调用console.log('boo'),同时继续使用其余的代码”。 这与event loop有关,talk已经很好地解释了这一点。

使用async lib,您可以使用eachSeries

async.eachSeries(
    rows,
    function(row, callback) {
      console.log('Processing ID: ' + row.id)
      setTimeout(function() { 
          console.log('boo')
          callback()
      }, 100)
    },
    function(){
        // is called when done
    }
)

eachSeries将等待每次迭代,直到调用回调。由于setTimeout是异步的,因此您需要在那里调用回调。

使用JSBin: https://jsbin.com/gequduhoma/1/edit?js,console

答案 1 :(得分:0)

以下是您解决问题的方法

const async = require('async');
const processingIds = ['a1', 'b2', 'c3'];

function test(aProcessingId, done) {
  setTimeout(function () {
    console.log('Processing ID: ' + aProcessingId);
    console.log('boo');
    done();
  }, 100);
}

function iteratee(aProcessingId, done) {
  test(aProcessingId, done);
}

async.each(processingIds, iteratee);

打印

Processing ID: a1
boo
Processing ID: b2
boo
Processing ID: c3
boo

您的代码存在问题:

async.each(rows, function(rows, callback) {         
  console.log('Processing ID: ' + rows.id); // #1
  test(); // #2
  callback();

#1 - async.each会立即触发所有行,这就是为什么console.log会立即为所有处理ID启动。

#2 - test()启动一个新的异步函数,在0.1秒内显示&#34;键入&#34; boo&#34;,每个列表项执行一次。因此,在打印完所有流程ID后0.1秒,boo出现