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

时间:2016-10-17 11:33:10

标签: javascript

我在for循环中调用call testSP('/tmp/test2.csv',''); 函数时遇到问题,这是我的下面的代码

代码块

then()

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

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

2 个答案:

答案 0 :(得分:1)

当你有一个需要并行异步处理的循环或数组时,你会构建一个由then返回的promise的数组,然后使用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”)及以后的

您可以在let循环中使用for处理,这意味着每次循环迭代都会获得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
        }
    );

答案 1 :(得分:0)

首先。在JavaScript中用var声明的变量是函数范围的,而不是块作用域,这意味着(因为回调是异步的)j在所有回调执行中都是3。您可以通过使用j声明变量let来解决这个问题,而不是阻止范围。

for (let j = 0; ...

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

如果没有,但是在完成所有回调后仍然可以采取行动仍然很重要,您可以将延迟存储在列表中并将其传递给Promise.all(yourDeferredList),这将在完成所有回调后进行回调。