【问题标题】:Chaining promises with promises inside then()在 then() 中将 promise 与 promise 链接起来
【发布时间】:2019-06-19 03:03:19
【问题描述】:

在这样的场景中你如何链接?

api 是一个在 http 请求后返回 promise 的函数。 auth 是一个函数,在 api 响应后返回一个promise,如果解决 api 被第二次调用,如果不是 auth 拒绝。

我试过这个,但我不仅要回到回调地狱,而且不起作用。

function api(query) {
   return new Promise(function(resolve, reject) {
     //DO SOME STUFF AND SOMETIMES resolves...
   })
}

function auth() {
   return new Promise(function(resolve, reject) {
     api("/foo").then(function(asset1) {
        api("/bar").then(function(asset2) {
           resolve(asset2);
        }).catch(function() {
           reject();
        })
     }).catch(function(error) {
        reject();
     })

   })
}

【问题讨论】:

  • 可以同时调用/foo/bar 还是/bar 依赖/foo 的结果?似乎从未使用过asset1。`

标签: javascript promise


【解决方案1】:

一种更简洁的方法:

return myFirstPromise.then( (returnFromFirst) => {
    //Do something
    return secondPromise();
}).then( (returnFromSecond) => {
    //Do something
    return thirdPromise();
}).then( (returnFromThird) => {
    //All Done
}).catch( (e) =>{}
    console.error("SOMETHING WENT WRONG!!!");
);

【讨论】:

    【解决方案2】:

    据我了解您正在尝试做什么,以下代码也将使用asset2 解决。除此之外我猜api函数正在做http请求,所以你可以从使用request-promise lib而不是用new Promise东西转换回调api中受益。

    function api(query) {
       return new Promise(function(resolve, reject) {
         //DO SOME STUFF AND SOMETIMES resolves...
       })
    }
    
    function auth() {
       return api("/foo")
       .then(() => api("/bar"))
    }
    

    有了这个调用者会做这样的事情:

    auth()
    .then(asset2 => ...)
    .catch(err => ...)
    

    如果调用api 的顺序不重要,就像@styfle 在评论中指出的那样,您可以使用Promise.all 编写它

    function auth () {
      return Promise.all([
        api("/foo"),
        api("/bar")
      ])
    }
    

    【讨论】:

      【解决方案3】:

      我认为这应该对你有所帮助。

      只是一个观察:then 方法总是根据先前的承诺解决方案返回一个承诺。如果前一个 Promise 已解决,它会将已解决的值传递给下一个 Promise。否则它会将错误发送到catch 方法。

      function auth () {
        /*
          Since `then` already returns a new Promise, 
          you don't need to create a new Promise.
        */
        return api('/foo').then(function (asset1) {
          return api('/bar')
        })
      }
      
      /*
        So you can call auth:
      */
      
      auth().then(function (asset2) {
        console.log('This is my asset2:', asset2)
      }).catch(function (error) {
        console.error('Error', error)
      })
      

      【讨论】:

        【解决方案4】:

        来自Promises standard

        如果 x 是一个承诺,采用它的状态 [3.4]: 如果 x 处于待处理状态,则 Promise 必须保持待处理状态,直到 x 被满足或拒绝。 如果/当满足 x 时,以相同的值履行承诺。 如果/当 x 被拒绝时,以同样的理由拒绝承诺。

        下一个例子打印'finalVal':

        let resolveP1 = null;
        
        let p1 = new Promise(function(resolve, reject) {
            resolveP1 = resolve;
        });
        
        let p2 = new Promise(function(resolve, reject) {
            resolve(p1);
        });
        
        let p3 = p2.then(function(finalVal) {
            console.log(finalVal);
        });
        
        resolveP1('finalVal')
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-05-24
          • 1970-01-01
          • 1970-01-01
          • 2017-10-16
          • 1970-01-01
          • 2023-03-26
          • 2019-09-18
          • 2020-04-17
          相关资源
          最近更新 更多