繁体   English   中英

正确使用for循环和promises

[英]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回调中使用ithen可能会发生您正在考虑的问题(由该问题及其答案讨论)。 但是在使用它的地方,将其作为参数传递给函数,则不会发生,因为这与闭包无关。 再次,关键是将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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM