Node.js async forEach:线程安全吗?

时间:2014-12-18 21:11:39

标签: javascript node.js multithreading asynchronous async.js

我有一个(也许是微不足道的)问题。我正在使用Node.js包async,特别是async.each方法(https://github.com/caolan/async#forEach)。

请考虑以下代码:

var arrayOne=[];

async.forEach(arrayTwo, 
  function (item, callback){ 
    arrayOne.push(item); // push into arrayOne
    callback(); // the iterator has completed
  }, function(err) {
   // do something with arrayOne
}); 

arrayOne.push(item)安全吗?

1 个答案:

答案 0 :(得分:2)

所以这里的答案有点微妙。对于这种情况,您最终会得到与arrayOne具有相同顺序的arrayTwo,但这更像是示例代码不是真正异步的副作用{{1不做任何过于意外/聪明的事情。但是,为了使其真正可靠,您希望使用async.forEach函数来保证订单,而async的合同中的函数则不然。 .forEach/.each仅保证在.each中的每个项目都会调用一次worker函数。它并不能保证它会按顺序启动它们或等待一个完成后再启动下一个等等。如果async的作者决定以相反的顺序启动worker函数以进行某些性能优化,例如,那会改变你的副作用。因此,最好不要依赖于async函数的定义/文档中明确保证的任何行为。因此,使用类似arrayTwo之类的内容会为您提供一种可靠的方法,而不会在async.series结束时获得意外顺序。当然,并行性特征现在差别很大。

但是,从技术角度来看,不涉及“线程安全”的概念,因为节点只有一个执行线程。但是,在处理这样的异步代码时,最终会遇到相同类型的竞争条件,因此在一天结束时,您可以像在多线程语言中一样编写节点中的竞争条件。

我记住的最有用的类比是异步代码通过交付订购食物。如果您打电话给3家餐馆,并从每家餐馆订购一份披萨,那并不意味着送货到达门口的订单。