Как связать воедино вложенные обещания, содержащие блоки и тогда? - PullRequest
1 голос
/ 21 мая 2019

Как связать ES6 вложенность Promises с каждым Promise во вложении, имеющем блоки then и catch?

Например, что будет эквивалентно реализации цепочки блоков Promise then и catch для следующих вложенных реализаций вызовов AJAX, обработанных обратными вызовами success и error, учитывая, что каждый вызов API возвращает Promise * * 1015

$.ajax({ 
    url: 'url1', 
    success: function() {
        console.log('URL1 call success');
        $.ajax({    
            url: 'url2',
            success: function() {
                console.log('URL2 call success');
            },
            error:function() {
                console.log('URL2 call error');
            }
         })
    },
    error: function() {
        console.log('URL1 call error');
        $.ajax({
            url: 'url3',
            success: function() {
                console.log('URL3 call success');
            },
            error:function() {
                console.log('URL3 call error');
            }
         })
    }})

Ответы [ 3 ]

1 голос
/ 21 мая 2019

Если вы хотите связать обещания, вы можете сделать так, чтобы каждый обработчик возвращал обещание, а затем оттуда связывает функции then и catch. Я считаю, что это демонстрирует то, что вы хотите сделать:

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, как только ваши обработчики ошибок возвращают действительные обещания, оставшаяся часть цепочки не может сказать, было ли то, что было раньше, результатом успеха или обработчиками ошибок. Здесь нет логики ветвления, и для этого нужно вложить обещания.

Здесь есть две основные альтернативы. Сначала вы можете выдавать разные типы ошибок и обрабатывать каждую отдельную ошибку в одном обработчике catch. Во-вторых, вы можете использовать синтаксис async / await. Любой из них может работать на вас, но я думаю, что они требуют отдельного вопроса.

0 голосов
/ 21 мая 2019

вы пробовали .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>
0 голосов
/ 21 мая 2019

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