В этом упрощенном примере я вызываю три функции, когда выполняется первое обещание.
var test = new Promise(function (res, err) { setTimeout(res, 3000) })
test.then( () => { console.info("A") });
test.then( () => {
return new Promise(function(res, err) {
setTimeout(()=> { console.info("C");
res() }, 3000)
});
});
test.then( () => { console.info("B") });
Ожидаемый результат - A B C.
Предположим, я хочу вызвать третий .then для консоли B только тогда, когда будет выполнено второе обещание.
Если я попытаюсь сохранить второе обещание (myProm) в global и прикрепить к нему функцию .then, я получу (разумно) TypeError, потому что во время компиляции myProm все еще не определен.
var test = new Promise(function (res, err) { setTimeout(res, 3000) })
var myProm;
test.then( () => { console.info("A") });
test.then( () => {
myProm = new Promise(function(res, err) {
setTimeout(()=> { console.info("C");
res() }, 3000)
})
return myProm;
});
myProm.then( () => { console.info("B") });
Как мне продолжить? Как лучше всего связать два обещания вместе, чтобы возвращаемый объект Promise от одного .then должен был быть разрешен, прежде чем мы сможем выполнить следующий then?
В этом сценарии результат, который я хотел бы получить, будет A C B.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Каждый раз, когда вы вызываете .then, вы создаете новыйPromise, который разрешается, когда разрешается Promise, возвращенный этим .then. Вы должны назначить результат myProm, содержащего .then, переменной, а затем вызвать .then для этой переменной:
var test = new Promise(function (res, err) { setTimeout(res, 500) })
var myProm;
test.then( () => { console.info("A") })
.then( () => {
myProm = new Promise(function(res, err) {
setTimeout(()=> { console.info("C");
res() }, 500)
})
return myProm;
})
.then( () => { console.info("B") });Большую часть времени при использовании Promises вы должны соединять цепочки .then следующим образом. Выполняйте prom.then(...) ... prom.then(...) только тогда, когда вы хотите инициализировать две асинхронные операции полностью отделить при разрешении prom.
> Каждый раз, когда вы вызываете .then, вы создаете новое Promise, которое разрешается, когда Promise, возвращенный этим .then, разрешается. это неявное обещание? можешь указать на спецификацию?
Это полноценный Promise, совсем не подразумеваемый. См. Заметки MDN о сцеплении
then возвращает обещание, которое разрешается, когда указанная функция была запущена и возвращенное значение было разрешено (это небольшое упрощение, но достаточное для данной задачи).
Следовательно, привязать обещание к результату then. Просто подключите другой .then:
var test = new Promise(function (res, err) { setTimeout(res, 3000) })
test.then( () => { console.info("A") });
test
.then( () => {
return new Promise(function(res, err) {
setTimeout(()=> { console.info("C"); res() }, 3000);
});
})
.then( () => { console.info("B") });… И не забывайте ключевое слово return в обратном вызове then.
@Bergi, что произойдет, если вы пропустите оператор return, он неявно возвращает undefined?
@leonardofed Да, но тогда он не будет ждать обещания, которое вы создали в обратном вызове, а только для undefined.
@Bergi, хорошо, это означает, что обещание будет немедленно разрешено как undefined, и это нарушит асинхронность моего кода. Правильный?
@leonardofed Да, если вы удалите return из строки 6 моего кода выше, то, например, B будет зарегистрирован раньше, чем C.
test.then(...).then(...)… ?!