我有一个关于原生数组的问题。JavaScript的每一个实现都是异步的吗? 例如,如果我调用:

[many many elements].forEach(function () {lots of work to do})

这将是非阻塞的吗?


当前回答

在npm中有一个包,可以为每个循环提供简单的异步。

var forEachAsync = require('futures').forEachAsync;

// waits for one request to finish before beginning the next 
forEachAsync(['dogs', 'cats', 'octocats'], function (next, element, index, array) {
  getPics(element, next);
  // then after all of the elements have been handled 
  // the final callback fires to let you know it's all done 
  }).then(function () {
    console.log('All requests have finished');
});

这也是allasync的另一个变体

其他回答

如果您需要一个异步友好的Array版本。对于ach和类似的,它们在Node.js 'async'模块中可用:http://github.com/caolan/async…作为奖励,这个模块也可以在浏览器中工作。

async.each(openFiles, saveFile, function(err){
    // if any of the saves produced an error, err would equal that error
});

下面是一个小例子,你可以运行来测试它:

[1,2,3,4,5,6,7,8,9].forEach(function(n){
    var sum = 0;
    console.log('Start for:' + n);
    for (var i = 0; i < ( 10 - n) * 100000000; i++)
        sum++;

    console.log('Ended for:' + n, sum);
});

它将生成如下内容(如果花费的时间太少/太多,可以增加/减少迭代次数):

(index):48 Start for:1
(index):52 Ended for:1 900000000
(index):48 Start for:2
(index):52 Ended for:2 800000000
(index):48 Start for:3
(index):52 Ended for:3 700000000
(index):48 Start for:4
(index):52 Ended for:4 600000000
(index):48 Start for:5
(index):52 Ended for:5 500000000
(index):48 Start for:6
(index):52 Ended for:6 400000000
(index):48 Start for:7
(index):52 Ended for:7 300000000
(index):48 Start for:8
(index):52 Ended for:8 200000000
(index):48 Start for:9
(index):52 Ended for:9 100000000
(index):45 [Violation] 'load' handler took 7285ms

虽然数组。forEach不是异步的,你可以得到异步的“最终结果”。在下面的例子:

delayFunction(x) { 归还新承诺( (resolve) => setTimeout(() => resolve(x), 1000) ); } [1,2,3].forEach(async(x) => { console.log (x); console.log(等待delayFunction (x)); });

甚至可以像这样编码解决方案,例如:

 var loop = function(i, data, callback) {
    if (i < data.length) {
        //TODO("SELECT * FROM stackoverflowUsers;", function(res) {
            //data[i].meta = res;
            console.log(i, data[i].title);
            return loop(i+1, data, errors, callback);
        //});
    } else {
       return callback(data);
    }
};

loop(0, [{"title": "hello"}, {"title": "world"}], function(data) {
    console.log("DONE\n"+data);
});

另一方面,它比“for”慢得多。

否则,优秀的Async库可以这样做:https://caolan.github.io/async/docs.html#each

不,它堵塞了。看一下算法的说明。

然而,MDN上给出了一个可能更容易理解的实现:

if (!Array.prototype.forEach)
{
  Array.prototype.forEach = function(fun /*, thisp */)
  {
    "use strict";

    if (this === void 0 || this === null)
      throw new TypeError();

    var t = Object(this);
    var len = t.length >>> 0;
    if (typeof fun !== "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in t)
        fun.call(thisp, t[i], i, t);
    }
  };
}

如果你必须为每个元素执行大量代码,你应该考虑使用不同的方法:

function processArray(items, process) {
    var todo = items.concat();

    setTimeout(function() {
        process(todo.shift());
        if(todo.length > 0) {
            setTimeout(arguments.callee, 25);
        }
    }, 25);
}

然后用:

processArray([many many elements], function () {lots of work to do});

这将是非阻塞的。这个例子来自于高性能JavaScript。

另一个选择可能是网络工作者。