用数组中的满足值替换promise项

时间:2017-08-03 16:41:20

标签: javascript arrays for-loop promise es6-promise

以下是我将用作参考的代码示例。

var promises = [];
for (var i = 0; i < arrayCars.length; i++) {
  promises.push(downloadSpecs({ // function downloadSpecs returns a promise which later resolves a JSON
    model: arrayCars[i]
  }));
}

Promise.all(promises).then(function(output) {
  for (var i = 0; i < output.length; i++) {

    var preownedMiles = output[i].preownedMiles;
    var zipRadius = output[i].zipcodeRadius;

    if ('discount' in output[i]) {

      featuredCars.models.push({
        "name": output[i].modelName,
        "type": output[i].bodyType,
        "value": output[i].salePrice,
        "photos": []
      });

    }

    if (preownedMiles > 10000) {

      featuredCars.models.push({
        "name": output[i].modelName,
        "type": output[i].bodyType,
        "value": output[i].salePrice - 3000,
        "photos": []
      });

      featuredCars.models.photos[featuredCars.models.photos.length - 1].push(downloadImg({ // function downloadImg returns a promise which resolves the downloaded path
          urls: output[i].picURLS,
          saveThumbnail: false
        }));
    }

    if (zipRadius < 6) {

      featuredCars.models.push({
        "name": output[i].modelName,
        "type": output[i].bodyType,
        "value": output[i].salePrice - 1000,
        "photos": []
      });
      featuredCars.models.photos[featuredCars.models.photos.length - 1].push(downloadImg({ // function downloadImg returns a promise which resolves the downloaded path
          urls: output[i].picURLS,
          saveThumbnail: false
      }));
    }
  }
}

正如你所看到的那样,循环执行&#34; promises&#34;数组应包含一堆promise数据对象。我使用Promise.all()。then()在下一个块中解析。如果您根据某些条件看到&#34;照片&#34; &#34; featuredCars.models&#34;的关键字对象再次设置为Promise对象(作为函数&#34; downloadImg&#34;返回Promise对象)。我不能改变任何这些功能的行为,因为它们是我使用的库的一部分,我无法控制它们。

所以我正在寻找一种方法来迭代&#34; featuredCars.models&#34;对象和 取代&#34;照片的价值&#34;具有各自Promise对象的实现值的数组。

到目前为止,我一直试图用for循环来做,我观察到如果我做了#34; featuredCars.models.photos&#34;的Promise.all(),我就不会有权访问循环计数器,以便我可以替换&#34; featuredCars.models.photos&#34;在&#34; .then()&#34;。

中解决其承诺

我认为我需要将循环计数器传递给.then(),以便我知道需要替换对象的哪个索引,而不是每个&#34;照片&#34; array包含一个Promise对象。

我尽力让自己尽可能清楚。如果我听起来含糊不清,请耐心等待。

1 个答案:

答案 0 :(得分:1)

如果要在异步操作返回后使用循环计数器变量,则应使用块作用域变量(letconst)或创建新闭包。

在此处查看问题:

for (var i = 0; i < 10; i++) {
    setTimeout(function() { console.log(i) }, 0)
}

不是记录&#34; 0&#34;,&#34; 1&#34;,...,&#34; 9&#34;而是记录&#34; 10&#34; 10次​​,因为一旦回调触发,循环已经终止。

在ES6中使用let

for (let i = 0; i < 10; i++) {
    setTimeout(function() { console.log(i) }, 0)
}

关闭:

for (var i = 0; i < 10; i++) {
    (function(iInLoop) {
        setTimeout(function() {
             console.log(iInLoop)
        }, 0)
    })(i)
}

如果您执行其中任何一项或那些操作,则可以向照片承诺添加then(),该承诺将根据该循环周期中i的值更新数组中的值。