然后在Promise中返回Promise链

时间:2018-08-15 06:28:46

标签: javascript promise axios

我想使用axios获取API,该API返回objectId的数组列表。获取列表objectId之后,我想使用promise提取对象的详细信息

我想到这样的东西

var objectDetail = [];

axios.get('apiendpoint/')
.then((response) => {
  var listOfObjectId = response.data;
  var chain = Promise.resolve()
  for (var objectId of listOfObjectId) {
    chain = chain.then(axios.get(`apiendpoint/${objectId}`)
      .then((response) => {
        objectDetail.push(response.data);
      })
    );
  }
  return chain;
}).then((chain) => {
  console.log(chain);
  return chain;
})

上面的代码返回undefined,promise链对象没有传递给then方法调用。我的方法错误还是我错过了什么?谢谢

这里是我读过的书架,可能与之相关:

2 个答案:

答案 0 :(得分:5)

承诺链 被传递到最终.then,但是承诺链没有返回任何内容:请参见

.then((response) => {
  objectDetail.push(response.data);
})

该函数不返回任何内容。如果您想在链的末尾使用objectDetail而不引用外部变量,请同时使用return

.then((response) => {
  objectDetail.push(response.data);
  return objectDetail;
})

但是请注意

}).then((chain) => {
  console.log(chain);
  return chain;
})

有点多余-除非您只是为了log而这样做,否则最好完全将其保留。

如果您使用Promise.all代替,您的代码将会更清晰:

axios.get('apiendpoint/')
  .then(({ data }) => Promise.all(
    data.map(objectId => (axios.get(`apiendpoint/${objectId}`)
      .then(res => res.data)
    ))
  ));

答案 1 :(得分:1)

您不能兑现承诺。如果您从then( onfulfilled)处理程序中返回了一个Promise,则Promise代码将等待返回的Promise被结算,然后再解决或拒绝具有成功或失败值的链中的下一个Promise。返回承诺。

所以

//...
  return chain;
}).then((chain) => {
  console.log(chain);
  return chain;
})

令人困惑-第一行中返回的chain承诺不会传递给下一个then处理程序。成功完成后,传递的是fulfilled中最后一个承诺的chain值。但是,由于chain中的处理程序未明确返回值,因此它将为undefined

选项包括:

  • 出于调试目的,可以选择在完整构造chain之前记录其值,然后从第一个then处理程序返回chain
  • 忽略传递给最终then成功处理程序的实际值,并使用该值来指示objectDetail包含有效数据,或者
  • 在第一个then处理程序中创建objectDetail,并从构造期间添加到chain的promise处理程序中返回它。

    axios.get('apiendpoint/')
    .then((response) => {
        var listOfObjectId = response.data;
        var objectDetail = [];
        var chain = Promise.resolve()
        for (var objectId of listOfObjectId) {
            chain = chain.then(axios.get(`apiendpoint/${objectId}`)
            .then((response) => {
                objectDetail.push(response.data);
                return objectDetail; // return details array
            });
        }
        return chain;
    })
    .then( objectDetail) => {
        // process objectDetail
    })
    .catch(err=> console.log(err););
    

上述方法按顺序处理详细请求。可以使用Promise.all重写该请求,以并行发出详细请求。