Я новичок в JS Promises и пытаюсь понять, почему я получаю разные результаты в зависимости от того, есть ли у меня возврат или нет в этой строке: return foo(2).then(() => {
function foo(num) {
console.info(num)
return new Promise(resolve => setTimeout(resolve, num * 1000));
}
foo(1).then(() => {
return foo(2).then(() => {
console.info(4)
});
}).then(() => {
foo(3)
})
против
function foo(num) {
console.info(num)
return new Promise(resolve => setTimeout(resolve, num * 1000));
}
foo(1).then(() => {
foo(2).then(() => {
console.info(4)
});
}).then(() => {
foo(3)
})
Почему порядок 4/3 меняется?
Вызов .then(someFn)
создает новое обещание. Это обещание приведет к тому, что someFn
вернется. Если someFn
возвращает undefined
, как в вашем втором примере, то новое обещание может сразу же разрешиться в undefined
. Если someFn
возвращает обещание, как в вашем первом примере, то он должен дождаться разрешения внутреннего обещания, прежде чем внешнее обещание узнает, с каким значением оно должно быть решено.
Короче говоря: если вы возвращаете внутреннее обещание, вы заставляете внешнее обещание ждать его.
Разница в поведении связана с тем, как цепочка обещаний и возвращаемые значения.
ВНУТРЕННЕЕ ОБЕЩАНИЕ ВОЗВРАЩЕНИЕ
function foo(num) {
console.info(num);
return new Promise(resolve => setTimeout(resolve, num * 1000));
}
foo(1).then(() => {
return foo(2).then(() => {
console.info(4);
});
}).then(() => {
foo(3);
});
foo(1) запускается и печатает 1. Он возвращает обещание, которое выполняется через 1 секунду. Через 1 секунду вызывается первое обещание. Он возвращает обещание из foo(2). foo(2) запускается и печатает 2. Он возвращает обещание, которое разрешается через 2 секунды. Через 2 секунды внутренний процессор печатает 4.
Затем внешний ожидает завершения внутреннего, поскольку внутреннее обещание было возвращено. После того, как внутреннее обещание разрешается, выполняется внешнее. FinallSy, foo(3) запускается и печатает 3.
НЕ ВОЗВРАЩАЕМ ВНУТРЕННЕЕ ОБЕЩАНИЕ
function foo(num) {
console.info(num);
return new Promise(resolve => setTimeout(resolve, num * 1000));
}
foo(1).then(() => {
foo(2).then(() => {
console.info(4);
});
}).then(() => {
foo(3);
});
foo(1) запускается и печатает 1. Он возвращает обещание, которое разрешается через 1 секунду. После 1 секунды вызывается первый, foo(2) запускается и печатает 2. Он возвращает обещание, которое разрешается через 2 секунды, но это обещание тогда не возвращается во внешний мир. Тогда внешний код не ждет завершения foo(2) и продолжает работу немедленно. foo(3) запускается и печатает 3 после выполнения первого обещания, не дожидаясь завершения foo(2). Через 2 секунды после запуска foo(2) внутренний код печатает 4.
возвращая внутреннее обещание. Внешний затем ждет разрешения внутреннего обещания, прежде чем продолжить. так что foo(3) запускается после завершения foo(1) и foo(2). когда не возвращается внутреннее обещание. Внешний тогда не ждет разрешения внутреннего обещания, поэтому foo(3) запускается сразу после завершения foo(1), независимо от foo(2).
с возвратом вы связываете обещания, без возврата вы просто выполняете какой-то код во внешнем
then
. Вы можете прочитать: javascript.info/promise-chaining