在javascript中为数组循环创建异步函数?

时间:2017-07-21 08:31:02

标签: javascript arrays asynchronous

我从未(故意!)使用javascript中的异步函数。 我必须做一个任务,要求我使用数组元素的异步函数(即for(let i=0;i<array.length;i++){do_Something_Async_here()})来在PARALLEL中处理它们。

我尝试过像这样使用setTimeout

unique.forEach(function (number, index)
   {
       setTimeout( populateResults(index,number), 0 );
   });
function populateResults(index,number)
{
   alert("populating results: index:"+index+" number:"+number);
   var jp;
   for(var i=0;i<1000000;i++)
   {
       jp=Math.pow(2,100);
   }
   alert("results populated: index:"+index+" number:"+number);
   return jp;
}

并且喜欢这个

let promises = [];
for (var i=0;i<unique.length;i++) {
    promises.push(populateResults(i,unique[i]));
}

Promise.all(promises).then(function(results){
   console.log(results);
}).catch(function(err) {
    // handle error here
});

我实际上对数字和索引做了一些事情,但我在这里简化了它。 现在,当我运行代码时,在这两种情况下,似乎我通常在C或java中执行代码。顺序。我错过了什么?如何使它们并行运行? 提前谢谢。

1 个答案:

答案 0 :(得分:0)

Javascript中的异步函数是立即返回Promise并在将来某个点完成运行的函数。

与C或Java不同,Javascript只是单线程的,因此不要将异步函数误认为是在一个单独的线程中运行的函数:所有代码都在同一个线程中运行,因此完全按顺序运行。你可以在异步javascript函数中做的就是延迟完成工作直到一段时间之后。

这意味着异步函数对于获取某些远程数据或超时的代码非常有用,或者在继续之前等待来自用户的事件。

您可以使用setTimeout

在此处模拟异步函数
function delayedPopulateResults(index, number) {
    return new Promise(function(resolve) {
        setTimeout(function() { resolve(populateResults(index, number); },
            Math.random());
    });
}

现在,如果您拨打delayedPopulateResults而不是populateResults,您的第二个代码块将创建所有承诺并在完成后记录结果。但请记住,所有这一切都是在代码执行之前引入一个随机延迟:因此对populateResults()的调用将以随机顺序执行,但仍然必须在下一个运行之前完成每个调用。

如果您可以使用最新版本的Ecmascript(ES7),那么您可以使用asyncawait关键字来简化此操作,但要在浏览器中运行代码,您可能需要使用诸如Babel或Typescript之类的转换器在ES5中呈现代码。