遍历对象数组,为每个对象调用promise,并在完成时记录日志

时间:2019-03-02 02:28:18

标签: javascript object ecmascript-6 promise es6-promise

在此问题中,我试图遍历从promise检索到的对象数组,并为该数组中的每个对象分配所需的对象 打电话给另一个诺言。调用所有这些诺言后,我想将DONE登录到控制台。

我怎么知道所有的承诺何时完成?

function myFunction() {
  fetch("https://jsonplaceholder.typicode.com/albums").then(first_response => {
    first_response.json().then(function(value) {
      for (var i = 0; i < value.length; i++) {
        fetch("https://jsonplaceholder.typicode.com/users")
          .then(second_response => second_response.json())
          .then(value => console.log(value))
      }
      console.log("DONE!!");
    });
  });
}

myFunction();
.as-console-wrapper { max-height: 100% !important; top: 0; }

3 个答案:

答案 0 :(得分:0)

使用Array.prototype.mapvalue数组转换为Promises数组,然后在该数组的.then上调用Promise.all。您还应该避免Promise-as-callback反模式,仅将return中的Promise从一个.then链接到下一个.then,而不创建不必要的嵌套:

function myFunction () {
  fetch("https://jsonplaceholder.typicode.com/albums")
    .then(first_response => first_response.json())
    .then(arr => Promise.all(arr.map(item => 
       fetch("https://jsonplaceholder.typicode.com/users")
       .then(second_response => second_response.json())
       .then(value => console.log(value))
      )))
    .then(() => {
      console.log("DONE!!");      
    });
}

myFunction();

请注意,除了结果数组的长度外,当前代码在第一个响应中似乎没有使用任何东西,这很奇怪-如果要使用要迭代的项(以创建新的URL) (例如,要获取),请在上面的映射函数中使用item变量。

答案 1 :(得分:0)

您需要将promise收集到一个数组中,并使用Promise.all()以便在完成所有操作后提供回调。最简单的方法是将您的for循环更改为对Array.prototype.map()的调用:

function myFunction() {
  fetch("https://jsonplaceholder.typicode.com/albums").then(first_response => {
    return first_response.json();
  }).then(function(value) {
    const promises = value.map((_, i) => {
      return fetch("https://jsonplaceholder.typicode.com/users")
        .then(second_response => second_response.json())
        .then(value => console.log(value))
    });
    return Promise.all(promises);
  }).then(() => console.log("DONE!!"));
}

myFunction();
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 2 :(得分:0)

您可以使用es6功能承诺功能将所有提取请求放在一起,如果所有承诺都完成,则可以完成打印。

    function myFunction () {
  var promises = [];
  var promise = undefined;
   fetch("https://jsonplaceholder.typicode.com/albums").then(first_response => {
       first_response.json().then(function(value) {
            for (var i = 0; i < value.length; i++){
              promise = fetch("https://jsonplaceholder.typicode.com/users/?id="+value[i].id)
                  .then(second_response => second_response.json())
                  .then(value => console.log(value))   
              promises.push(promise)
            }
        Promise.all(promises).then(function(){ console.log("Done!");});
       });
   });
}

https://codepen.io/Shajith/pen/vPGGPJ?editors=0010