[英]Proper use of for loops and promises
循环遍历具有x个项目的数组,我正在循环内执行一个promise。 promise的参数依赖于递增值(即i
的当前值)。
我想知道实现此功能的正确/最佳方法是什么,以便确保将i
的正确值解析为承诺。
这是代码结构的示例。
for (var i = 0; var < array.length; ++i) {
SomePromise.get(i).then(function(result) {
console.log(result);
}).catch()......
}
正如您所收集的那样, i
可能/最终将是解析为承诺之前所获得的增量的最终值。 那就是说,在执行promise之前,循环已经执行到最后,而使i的值无论数组的长度如何。
正如您所收集的那样,
i
可能/最终将是解析为承诺之前所获得的增量的最终值。
不是你用i
的方式。 这段代码:
SomePromise.get(i)...
...获取i
的值并将其传递给get
。 一旦get
接收到它,该值就不会以任何方式连接到i
变量,因此get
对其进行处理并不重要。
如果您在then
回调中使用i
, then
可能会发生您正在考虑的问题(由该问题及其答案讨论)。 但是在使用它的地方,将其作为参数传递给函数,则不会发生,因为这与闭包无关。 再次,关键是将i
的值传递给get
,而不是对i
变量的某种引用(JavaScript没有任何形式的传递引用,只是闭包)。
就将权利i
传递给代码并对结果进行处理而言,该代码很好。
这是一个很好的演示(要求您的浏览器支持Promise
):
function getSomePromise(value) { return new Promise(function(resolve) { resolve(value); }); } var array = [1, 2, 3, 4]; for (var i = 0; i < array.length; ++i) { getSomePromise(i) .then(function(result) { var p = document.createElement("p"); p.innerHTML = "Result is " + result; document.body.appendChild(p); }); // catch omitted for brevity }
...并演示了如何在then
回调中使用i
会产生您担心的效果(取决于代码目标,这是好是坏):
function getSomePromise(value) { return new Promise(function(resolve) { resolve(value); }); } var array = [1, 2, 3, 4]; for (var i = 0; i < array.length; ++i) { getSomePromise(i) .then(function(result) { var p = document.createElement("p"); p.innerHTML = "Result is " + result + ", i is " + i; document.body.appendChild(p); }); // catch omitted for brevity }
如果您需要在then
回调中使用i
并想要当时最新的版本(而不是最终版本),那么在这个问题上的假设越来越远,在这种情况下,您可能会使用array.forEach(function(entry, index) ...)
,然后使用index
,它不会改变:
function getSomePromise(value) { return new Promise(function(resolve) { resolve(value); }); } var array = [1, 2, 3, 4]; array.forEach(function(entry, index) { getSomePromise(index) .then(function(result) { var p = document.createElement("p"); p.innerHTML = "Result is " + result + ", index is " + index; document.body.appendChild(p); }); // catch omitted for brevity });
但这距离您的问题有点遥远。
如果不是必须使用for循环,则还可以考虑Array.prototype.forEach
。
array.forEach(function(arrayItem, i){
SomePromise.get(i).then(function(result) {
console.log(result);
}).catch()......
});
在功能性JavaScript领域,这与Promise等待的配合非常优雅:
Promise.all(array.map(function(arrayItem, i){
return SomePromise.get(i).then(function(result) {
console.log(result);
}).catch()......
}));
无论是通过for循环还是通过forEach / map,整数i
都会按值传递到函数中,因此不会影响循环中的增量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.