javascript for循环内的异步处理

javascript for循环内的异步处理,第1张

javascript for循环内的异步处理

for
启动所有异步 *** 作时,循环将立即运行到完成。当他们将来完成某个时间并调用其回调时,循环索引变量的
i
值将为所有回调的最后一个值。

这是因为

for
循环在继续循环的下一个迭代之前不会等待异步 *** 作完成,并且因为将来会调用异步回调。因此,循环完成其迭代,然后在这些异步 *** 作完成时调用回调。这样,循环索引被“完成”并且对于所有回调都处于其最终值。

要解决此问题,您必须为每个回调分别单独保存循环索引。在Javascript中,执行此 *** 作的方法是在函数闭包中捕获它。可以通过专门为此目的创建内联函数闭包来完成(如下所示的第一个示例),也可以创建一个外部函数,将索引传递给该函数,然后让它为您唯一地维护索引(如下所示的第二个示例)。

从2016年开始,如果您具有Javascript的完全最新的ES6实现,则还可以

let
用于定义
for
循环变量,并且将为循环的每次迭代唯一定义该变量
for
(下面的第三种实现)。但是,请注意,这是ES6实现中的最新实现功能,因此您必须确保执行环境支持该选项。

使用.forEach()进行迭代,因为它创建了自己的函数闭包

someArray.forEach(function(item, i) {    asynchronousProcess(function(item) {        console.log(i);    });});

使用IIFE创建您自己的函数闭包

var j = 10;for (var i = 0; i < j; i++) {    (function(cntr) {        // here the value of i was passed into as the argument cntr        // and will be captured in this function closure so each        // iteration of the loop can have it's own value        asynchronousProcess(function() { console.log(cntr);        });    })(i);}

创建或修改外部函数并将其传递给变量

如果可以修改该

asynchronousProcess()
函数,则可以在其中传递值,然后
asynchronousProcess()
将cntr函数返回回调,如下所示:

var j = 10;for (var i = 0; i < j; i++) {    asynchronousProcess(i, function(cntr) {        console.log(cntr);    });}

使用ES6

let

如果您有一个完全支持ES6的Javascript执行环境,则可以

let
for
循环中使用,如下所示:

const j = 10;for (let i = 0; i < j; i++) {    asynchronousProcess(function() {        console.log(i);    });}

let
在这样的
for
循环声明中声明的代码
i
将为每次循环调用创建一个唯一的值(这是您想要的)。

使用promise和async / await进行序列化

如果您的异步函数返回了一个Promise,并且您希望序列化异步 *** 作以使其依次而不是并行运行,并且您正在支持

async
和的现代环境中运行
await
,那么您将有更多选择。

async function someFunction() {    const j = 10;    for (let i = 0; i < j; i++) {        // wait for the promise to resolve before advancing the for loop        await asynchronousProcess();        console.log(i);    }}

这样可以确保一次只有一个呼叫

asynchronousProcess()
在进行中,并且
for
直到每个呼叫完成,循环才会进行。这与之前所有并行运行异步 *** 作的方案不同,因此它完全取决于所需的设计。注意:
await
与promise一起使用,因此您的函数必须返回在异步 *** 作完成后已解决/拒绝的promise。另外,请注意,要使用
await
该函数,必须声明contains函数
async

并行运行异步 *** 作并用于

Promise.all()
按顺序收集结果

 function someFunction() {     let promises = [];     for (let i = 0; i < 10; i++) {          promises.push(asynchonousProcessThatReturnsPromise());     }     return Promise.all(promises); } someFunction().then(results => {     // array of results in order here     console.log(results); }).catch(err => {     console.log(err); });


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4921426.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-12
下一篇 2022-11-12

发表评论

登录后才能评论

评论列表(0条)

保存