Почему тогда не соблюдается порядок обратных вызовов?

#javascript #asynchronous #promise #fetch

#javascript #асинхронный #обещание #выборка

Вопрос:

У меня есть следующий код:

 Promise
  .resolve('333')
  .then(()=>{setTimeout(()=>{Promise.resolve('123');},10000)})
  .then(()=>{console.log("should wait");});
 

Я думал, что вывод должен быть сначала «123», а затем «должен ждать». По неясной причине сначала печатается ‘should wait’. Я думал, что второй тогда не запустится, пока функция асинхронности (setTimeout) не завершится. Я читал, что это вся «магия» использования Promise и then . Теперь я очень смущен. Почему, например, этого не происходит, когда мы вызываем функцию выборки? функция выборки также является асинхронной, так почему тогда после выборки не запускается до завершения выборки?

Комментарии:

1. Ваша цепочка обещаний не ожидает истечения времени ожидания.

Ответ №1:

Если .then обратный вызов явно не возвращает обещание, следующий .then в цепочке гарантированно выполняется почти мгновенно после этого (он помещается в очередь микрозадач).

Прямо сейчас вы ничего не возвращаете, поэтому undefined возвращается, поэтому второй .then выполняется немедленно.

Если вы хотите, чтобы первое .then заставляло второе ждать окончания тайм-аута, верните обещание, которое разрешается по истечении тайм-аута:

 Promise.resolve('333')
    .then(() => {
        return new Promise((res) => {
          setTimeout(() => {
            res('123');
          }, 3000);
        });
     })
    .then(() => { console.log("should wait 3 seconds"); }); 

Комментарии:

1. Promise обязательно ли переносить setTimeout ? Разве не может быть по-другому: setTimeout завершит обещание?

2. Нет, потому что значение, возвращаемое обратным вызовом, должно быть обещанием. Обратный .then вызов не знает, что делать с идентификатором тайм-аута. Обещание должно обернуть setTimeout .

3. Правильно ли говорить, что в моем случае обещание считается выполненным немедленно и, следовательно, следующий затем может начаться немедленно?

4. В вашем исходном коде единственное обещание в цепочке — это исходное обещание, которое выполняется Promise.resolve('333') . Обещание внутри .then не возвращается из .then , поэтому следующий .then не ожидает его.