如何在 for 循环中同步 then()



我在 for 循环中调用 then() 函数时遇到问题,这是我下面的代码

代码块

StretchData.getById(item).then(function (data) 

在 j==3 之后调用,但我的要求它应该调用每次迭代 知道如何实现这一点。我尝试了很多事情仍然没有结果。

for (var j = 0; j < 3; j++) {
                StretchData.getById(item)
                .then(function (data) {
                    alert(startWorkOutModel.sortValue);
                    startWorkOutModel.inStretchedData = {
                        sort: startWorkOutModel.sortValue,
                        sData: data.result
                    }
                    startWorkOutModel.stretchedData.push(startWorkOutModel.inStretchedData);
                    fl = true;
                    console.log(JSON.stringify(startWorkOutModel.stretchedData));
                    // break;
                },
                function (error) {
                    alert(JSON.stringify(error));
                });                            
      }

当你有一个需要并行异步处理的循环或数组时,你建立一个由then返回的承诺数组,然后使用 Promise.all 等待它们全部。您通常还会处理来自Promise.all而不是单独承诺的错误,除非您能够进行纠错并返回一些东西来代替错误。

大致如下:

var promises = [];
for (var j = 0; j < 3; j++) {
    promises.push(
        StretchData.getById(item)
            .then(function(data) {
                // *** Gets called for each individual item
                alert(startWorkOutModel.sortValue);
                startWorkOutModel.inStretchedData = {
                    sort: startWorkOutModel.sortValue,
                    sData: data.result
                }
                startWorkOutModel.stretchedData.push(startWorkOutModel.inStretchedData);
                fl = true;
                console.log(JSON.stringify(startWorkOutModel.stretchedData));
                // *** Normally you'd want to return something here
            })
    );
}
Promise.all(promises)
    .then(
        function(results) {
            // *** Use results (an array of the promise results) here
        },
        function(error) {
            // *** At least one promise failed
        }
    );

正如我在关于这个问题的评论中提到的,你没有在循环中使用j,所以它会连续三次做同样的事情。如果需要在 promise 回调代码中使用 j,则有两种选择:

ES5 及更早

版本

使用函数将j的值捕获到回调可以使用的不变变量中(因为j将在任何这些回调运行时3(:

function doRequestFor(value) {
    return StretchData.getById(item)
            .then(function(data) {
                // *** Gets called for each individual item
                // *** Use `value` here (in place of `j`)
                alert(startWorkOutModel.sortValue);
                startWorkOutModel.inStretchedData = {
                    sort: startWorkOutModel.sortValue,
                    sData: data.result
                }
                startWorkOutModel.stretchedData.push(startWorkOutModel.inStretchedData);
                fl = true;
                console.log(JSON.stringify(startWorkOutModel.stretchedData));
                // *** Normally you'd want to return something here
            });
}
var promises = [];
for (var j = 0; j < 3; j++) {
    promises.push(getRequestFor(j));
}
Promise.all(promises)
    .then(
        function(results) {
            // *** Use results here
        },
        function(error) {
            // *** At least one promise failed
        }
    );

ES2015(又名"ES6"(及更高

版本

您可以在for循环中使用let的处理,这意味着每个循环迭代都会获得自己的j副本:

let promises = [];
for (let j = 0; j < 3; j++) {
//   ^^^---------------------------- *** Note
    promises.push(
        StretchData.getById(item)
            .then(function(data) {
                // *** Gets called for each individual item
                // *** Use `j` here, it'll be 0, 1, or 2
                alert(startWorkOutModel.sortValue);
                startWorkOutModel.inStretchedData = {
                    sort: startWorkOutModel.sortValue,
                    sData: data.result
                }
                startWorkOutModel.stretchedData.push(startWorkOutModel.inStretchedData);
                fl = true;
                console.log(JSON.stringify(startWorkOutModel.stretchedData));
                // *** Normally you'd want to return something here
            })
    );
}
Promise.all(promises)
    .then(
        function(results) {
            // *** Use results (an array of the promise results) here
        },
        function(error) {
            // *** At least one promise failed
        }
    );

首先。在 JavaScript 中使用 var 声明的变量是函数范围的,而不是块范围的,这意味着(因为回调是异步的(在所有回调执行中j将为 3。您可以通过声明变量j来绕过这一事实,let 而不是阻止它的作用域。

for (let j = 0; ...

第二。回调串联运行是否重要?在这种情况下,您将不得不大量重构代码。也许使调用递归并将循环的下一个调用链接到第一个调用的回调。

如果没有,但当所有回调

都完成后,您可以采取行动仍然很重要,您可以将延迟存储在列表中并将它们传递给Promise.all(yourDeferredList)当所有回调完成后将回调。

最新更新