如何链接包含then和catch块的嵌套promise?

时间:2019-05-21 13:48:00

标签: javascript ecmascript-6 promise es6-promise

如何将嵌套ES6的{​​{1}}与嵌套的PromisesPromise块中的每个then链接起来?

例如,catch Promisethen的块链实现等效于以下由catch和{{处理的嵌套AJAX调用实现1}}回调,考虑到每个API调用都会返回一个success

error

3 个答案:

答案 0 :(得分:1)

如果要链接承诺,可以让每个处理程序返回一个承诺,然后从那里链接thencatch函数。我相信这可以说明您要做什么:

const getPromise = (time, reject=false) => new Promise((res, rej) => {
  setTimeout(() => reject ? rej() : res('done'), time);
});

getPromise(500)
  .then(() => {
    console.log('first response');
    return getPromise(500, false);
  })
  .then(() => {
    console.log('second response');
    return getPromise(500, true);
  })
  .catch((error) => {
    console.log('you can have catch statements return promises, too');
    return getPromise(700, true)
  })
  .then(() => {
    // this structure falls down here; is this a response to the promise returned from
    // the catch, or the promise returned from the 'second response' part?
    console.log('third response');
  })
  .catch(() => {
    console.error('hit an error');
  });

但是,重要的是要意识到这是一条没有分支逻辑的链。使用结构handle success-> handle error-> handle success,一旦您的错误处理程序返回了有效的Promise,链的其余部分就无法判断成功或错误的结果处理程序。这里没有分支逻辑,您需要嵌套promise才能实现。

这里有两个主要选择。首先,您可以抛出不同的错误类型,并在单个catch处理程序中处理每个不同的错误。其次,您可以改为使用async / await语法。两种方法都可以为您工作,但是我认为他们需要另外一个问题。

答案 1 :(得分:0)

This can be written like this :

function makeAjaxCall(url){
    return new Promise((s, f) => {
        $.ajax({ 
            url: url, 
            success: s,
            error: f
        })
    })
}
makeAjaxCall('url1')
.then((data) => {
    console.log('URL1 call success');
    return makeAjaxCall('url2')
}, (error) => {
    console.log('URL1 call error');
    return makeAjaxCall('url3')
})
.then(() => {
    //It Could be Either url2 success or url3 success
}, () => {
    //It Could be Either url2 failure or url3 falure
})

答案 2 :(得分:0)

您尝试过.done.fail吗?

您可以按以下方式重新编写代码

const doAjaxCall = (url) => $.ajax({ url })

const callURL = (url) => doAjaxCall(url)
  .done(() => console.log(`${url} is ok!`) )
  .fail(() => console.log(`${url} failed!`) );

doAjaxCall('/url1')
.done(() => {
  console.log('url1 is ok!');
  callURL('/url2');
 })
.fail(callURL('url3'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>