首页 文章

链接承诺与当然的承诺()

提问于
浏览
14

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

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

   })
}

3 回答

  • 4

    我认为这应该对你有帮助 .

    只是一个观察: then 方法总是根据先前的承诺解析返回一个承诺 . 如果先前的承诺得到解决,它会将已解决的值传递给下一个承诺 . 否则它会将错误发送到 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)
    })
    
  • 8

    来自Promises standard

    如果x是一个承诺,则采用其状态[3.4]:如果x处于未决状态,则承诺必须保持未决状态,直到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')
    
  • 4

    据我所知,你想要做什么,下面的代码也将解决 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")
      ])
    }
    

相关问题