简体   繁体   English

然后在Promise中返回Promise链

[英]return Promise chain inside Promise then

I want to fetch API using axios that return array list of objectId. 我想使用axios获取API,该API返回objectId的数组列表。 After I get the list objectId I want to fetch the detail of the object using promise 获取列表objectId之后,我想使用Promise获取对象的详细信息

I think of something like this 我想到这样的事情

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;
})

the code above returns undefined, the promise chain object is not passed to then method call. 上面的代码返回undefined,promise链对象没有传递给then方法调用。 Is my approach wrong or am I missing something? 我的方法错误还是我错过了什么? thank you 谢谢

Here are some stack I have read, might be related: 这是我已阅读的一些堆栈,可能与之相关:

The promise chain is being passed to the final .then , but the promise chain isn't returning anything : see your 该承诺链条传递到最后.then ,但承诺链不返回任何东西 :看你的

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

That function doesn't return anything. 该函数不返回任何内容。 If you wanted to use objectDetail at the end of the chain without referencing the outer variable, return it as well: 如果要在链的末尾使用objectDetail而不引用外部变量,请同样return它:

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

But note that 但请注意

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

is a bit redundant - unless you're only doing that in order to log the result, better just to leave it off entirely. 有点多余-除非您只是为了log结果,否则最好完全将其保留。

Your code would be clearer if you used Promise.all instead: 如果使用Promise.all代替,则代码将更清晰:

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

You can't fulfill a promise with a promise. 您不能兑现承诺。 If you return a promise from within a then( onfulfilled) handler, promise code waits for the returned promise to be settled before resolving or rejecting the next promise in a chain with the success or failure value of the returned promise. 如果您从then( onfulfilled)处理程序中返回承诺,则承诺代码将等待结算返回的承诺,然后再解决或拒绝具有返回的成功或失败值的链中的下一个承诺。

So 所以

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

is confusing - the chain promise returned in the first line is not passed to the next then handler. 令人困惑-该chain中的第一行返回承诺不会传递到下一个then处理。 What is passed is fulfilled value of the last promise in chain after it completes successfully. 成功完成后,传递的是chain最后一个承诺的fulfilled价值。 However, since handlers within chain don't explicitly return a value, this will be undefined . 但是,由于chain处理程序不会显式返回值,因此它将是undefined

Options include: 选项包括:

  • For debugging purposes, optionally log the value of chain after constructing it in its entirety before returning chain from the first then handler. 出于调试目的,可以选择在完整构造chain后将其值记录下来,然后再从第一个then处理程序返回chain
  • Ignore the actual value passed to the final then success handler and use it being called to indicate objectDetail contains valid data, or 忽略传递到最终的实际值then成功处理程序,并用它被称为指示objectDetail包含有效的数据,或
  • Create objectDetail in the first then handler and return it from promise handlers added to chain during construction. 在第一个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);); 

The method above processes detail requests sequentially. 上面的方法顺序地处理详细请求。 It could be rewriten using Promise.all for detail requests to be issued in parallel. 可以使用Promise.all ,以便同时发出详细请求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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