Существует важное различие: помните, что then
возвращает обещание (назовем его обещанием T). Когда вы делаете
return Promise.resolve(v + 1);
... вы решаете обещание T для обещания (назовем это обещанием B). Но когда вы делаете:
return v + 1;
... вы преобразуете обещание T в немедленное значение.
Преобразование обещания T в обещание B вводит дополнительную "галочку" в цикле разрешения,Вместо того чтобы обещание T поставило в очередь вызов своего обработчика разрешения, оно должно ждать, пока обещание B не вызовет обработчик разрешения T, который необходимо установить для него, и затем вызовет обработчик разрешения. Отсюда и дополнительный «тик» (в основном, другой цикл очереди микрозадач).
Более простой пример, обратите внимание, что он записывает «Second 2» * перед «First 2»:
Promise.resolve(1)
.then(v => Promise.resolve(v + 1))
.then(v => console.log(`First: ${v}`));
Promise.resolve(1)
.then(v => v + 1)
.then(v => console.log(`Second: ${v}`));
... тогда как, если у вас нет дополнительного обещания, он записывает «Первые 2» перед «Вторыми 2»:
Более простой пример,обратите внимание, что он записывает «Second 2» * перед «First 2»:
Promise.resolve(1)
.then(v => v + 1)
.then(v => console.log(`First: ${v}`));
Promise.resolve(1)
.then(v => v + 1)
.then(v => console.log(`Second: ${v}`));
Этот дополнительный тик был недавно удален для async
функций, выполняющих такие операции, как return await somePromise
(вместо просто return somePromise
), потому что его можно надежно удалить для собственных обещанийобрабатывается внутренне через async
/ await
. Но я не уверен, что это может быть надежно удалено для вашего случая, и / или получит ли это значительное внимание со стороны тех, кто должен был это сделать. Это потребует обработки нативного обещания, возвращенного из обработчика then
, отличного от любого другого thenable ¹, что может быть проблематично. (Но я не знаю наверняка, что это будет.)
¹ затем против обещание : https://promisesaplus.com