在一个包含x个项目的数组上循环我正在循环中执行一个promise。 promise使用一个依赖于递增值的参数(即i
的当前值。
我想知道实现此功能的正确/最佳方式是什么,以便确保将i
的正确值解析为promise。
这是代码结构的一个例子。
for (var i = 0; var < array.length; ++i) {
SomePromise.get(i).then(function(result) {
console.log(result);
}).catch()......
}
正如你将要收集的i
一样,/最终将成为解析为promise之前的最终增量值。也就是说,在执行promise之前循环已执行到结束,而i的值无论数组的长度是多少。
答案 0 :(得分:3)
正如你将要收集的
i
一样,/最终会成为在被解析为承诺之前所取得的最终增量值。
不是您使用i
的方式。这段代码:
SomePromise.get(i)...
...获取i
的值并将其传递给get
。一旦get
收到该值,该值就不会与i
变量任何关联,因此get
对它的作用无关紧要。
如果您在i
回调中使用then
,则会出现您正在考虑的问题(由this question and its answers讨论)。但是在你使用它的地方,将它作为参数传递给函数,它不会发生,因为它与闭包无关。关键是,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
}
...并演示如何在i
回调中使用then
会产生您所担心的影响(这取决于您的好坏)代码的目标):
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
}
如果您需要在i
回调中使用then
并且想要当时的,而不是最终的版本,那么在这个特殊情况下,您需要越来越假设且有点远离问题可能会使用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
});
但是你的问题有点远了。
答案 1 :(得分:1)
如果不必使用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
都将按值传递到函数中,因此不会影响循环中的增量。