使用 forEach 时与 node.js 异步流程混淆。

Confusion with node.js asynchronous flow when using forEach.

我在 node.js 中编码了 6 个月。我已经阅读了异步编码、事件循环和回调等概念。我知道“异步代码永远不会在同步代码堆栈执行时执行。这就是 node.js 是单线程的含义”。但这里有一个例子

var a = [4, 5, 6, 7];
var results = [];

a.forEach(function(result){
  results.push(result + 1);
});

console.log(results);

据我了解,函数 forEach 的参数是回调,它在同步块完成执行后稍后调用。这意味着我预计结果将是

[]

但实际上是

[5, 6 ,7, 8]

为什么会这样? forEach 是同步的吗?或者我错过了什么?据我了解,

console.log(results)

将在数据被推入之前执行。

某些功能是同步的,其他功能是异步的。事实上,Array.forEach方法和所有的基本功能是同步的。 如果您想异步操作数组,您有两种选择:在您的 forEach 中调用函数但您不知道它何时完成,或者使用 async library.

第一种方法:

var a = [4, 5, 6, 7];
var results = [];

a.forEach(function(result){
  (function(i){
    results.push(i);
  }(result+1));
});

console.log(results);

与 async.js :

var async = require('async');
var a = [4, 5, 6, 7];
var results = [];

async.eachSeries(a, function(result, done) {
  results.push(result+1);
  done();
}, function () {
  console.log('forEach finished');
});
console.log(results);

您传递给 Array.prototype.forEach() 的回调是同步的。因此,它会阻塞执行线程,直到它完成将函数应用于数组的所有成员。

如果您想进一步研究 JavaScript 的异步性质,我还找到了一些有趣的读物:

  • MDN - Array.prototype.forEach()

  • JavaScript, Node.js: is Array.forEach asynchronous?

    此线程解决了您当前面临的相同情况,并且 它还提供了 Array.prototype.forEach()

  • 的异步替代方案
  • Are all javascript callbacks asynchronous? If not, how do I know which are?