Есть много проблем с кодом выше.Одна из основных проблем, которая делает код трудным для отслеживания и отладки, заключается в том, что вы используете new Promise
там, где вам это не нужно. Как правило, если у вас есть new Promise
и логика в исполнителе обещания разрешит или отклонит в зависимости от результата другого обещания , вам не нужно использовать new Promise
.
Иногда у людей есть такой код:
function foo() {
const a = getValueSynchronously();
const b = getOtherValueSynchronously();
return doSomethingAsynchronous(a, b).then(x => x.someMethod());
}
Предположим, что doSomethigAsynchronous
возвращает обещание.Проблема с функцией foo
, описанной выше, состоит в том, что если getValueSynchronously
и getOtherValueSynchronously
не удаются, то foo
вызовет исключение, но если doSomethingAsynchronous
не удастся, то он отклонит обещание.Поэтому код, использующий foo
, должен обрабатывать синхронные исключения и асинхронные отклонения, если он хочет обработать все возможные сбои.Иногда люди чувствуют, что могут решить проблему, вызвав отказ от обещаний:
function foo() {
return new Promise((resolve, reject) => {
const a = getValueSynchronously();
const b = getOtherValueSynchronously();
doSomethingAsynchronous(a, b).then(x => x.someMethod()).then(resolve, reject);
});
}
В приведенном выше коде, если getValueSynchronously
или getOtherValueSynchronously
не пройден, это отказ от обещания.Но проблема с кодом выше в том, что легко ошибиться.Вы можете забыть позвонить reject
везде, где это необходимо.(На самом деле, у вас do есть эта ошибка в вашем коде. У вас есть вложенные обещания, отклонение которых не будет распространяться вверх. Они просто теряются, что означает, что при возникновении ошибки выкод просто остановится, и вы не поймете, почему. ) Или у вас может возникнуть соблазн вызвать `решить путь вниз во вложенной функции, что затрудняет выполнение логики.
Вы также можете сделать это:
function foo() {
return Promise.resolve().then(() => {
const a = getValueSynchronously();
const b = getOtherValueSynchronously();
return doSomethingAsynchronous(a, b);
}).then(x => x.someMethod());
}
Вы можете использовать Promise.resolve()
, чтобы войти в обетованный мир (хм ... "земля обетованная?").В приведенном выше коде вы не должны помнить, чтобы позвонить reject
.Если по какой-либо причине код внутри обратного вызова .then
завершается с ошибкой , вы получаете отклоненное обещание.
Я также заметил, что в некоторых местах вы возвращаете значение из функции executor, которую выперейти к new Promise
.Ваш код будет вести себя точно так же, если вы не используете return
там.Чтобы проиллюстрировать это, код:
function foo() {
return new Promise((resolve, reject) => {
return doSomethingAsynchronous().then(resolve, reject);
});
}
ведет себя точно так же, как этот код:
function foo() {
return new Promise((resolve, reject) => {
doSomethingAsynchronous().then(resolve, reject);
});
}
Значение, возвращаемое исполнителем, игнорируется,Конец истории.Если вы считаете, что значение, которое вы возвращаете от своих исполнителей, что-то делает, то это неверно.