正确使用for循环和承诺

时间:2016-04-06 07:26:32

标签: javascript for-loop promise

在一个包含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的值无论数组的长度是多少。

2 个答案:

答案 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都将按值传递到函数中,因此不会影响循环中的增量。