#javascript #promise
Вопрос:
У меня есть код для реализации Promise.race (), и он в основном работает. Однако в данном случае:
promiseRace([Promise.reject('test_error'), Promise.resolve('test_value')])
Я получаю test_value
вместо test_error
этого .
Почему это происходит?
const promiseRace = promises => new Promise((resolve, reject) => {
promises.forEach(p => {
if (
typeof p === 'object'
amp;amp; 'then' in p
amp;amp; typeof p.then === 'function'
) {
p.then(resolve).catch(reject);
} else {
resolve(p);
}
});
});
promiseRace([Promise.reject('test_error'),
Promise.resolve('test_value')]).then(value => { console.log(value); });
Комментарии:
1. Можете ли вы объяснить, почему, по вашему мнению, результат должен быть
test_error
таким ? Я знаюPromise.race
результатыtest_error
, но почему вы думаете, что ваш код тоже должен это делать? Расскажите нам о своих рассуждениях о том, для чего предназначена каждая строка в вашей функции, чтобы люди могли указать, где ваши предположения не совпадают с тем, как JS был разработан для работы. Кроме того, обратите внимание, что вам не нужно такое большое утверждение «если»,if (p instanceof Promise)
это все, что вам нужно. Также обратите внимание, что вы не заботитесь о сохранении»this
«, поэтому писать это как обычноfunction promiseRace(promises) { ... }
было бы нормально.2. Этот вариант менее красив, однако, если речь идет о двух вкладках (да, в этом случае instanceof оправдан), то с instanceof возникнут проблемы, потому что если вы передадите код с одной вкладки на другую — там будут разные объекты Promise
3. Это не имеет значения? Если это обещание,
p instanceof Promise
то это правда, конец. Передаете вы код или нет, не имеет значения: все, что является обещанием, является обещанием и, следовательно, является экземпляром типаPromise
объекта.4. Вместо того, чтобы самостоятельно выполнять проверку, просто позвоните
Promise.resolve(p)
5. @Mike’Pomax’Camermans Были бы — если бы обещания не были предшествующими символами 🙂
Ответ №1:
Это происходит потому, что в следующей строке вы вызываете .catch
другое (связанное) обещание, а не исходное обещание:
p.then(resolve).catch(reject);
Обратите внимание, что then
вызов не получает reject
аргумент обратного вызова, и поэтому существует дополнительный-промежуточный асинхронный цикл обещания. К моменту .catch
вызова обратного вызова ( reject
) другой случай уже был рассмотрен (выполненное обещание).
Поэтому измените на:
p.then(resolve, reject);