#javascript #es6-promise
#javascript #es6-обещание
Вопрос:
Пожалуйста, обратитесь к следующему JavaScript коду:
var arr = [30, 40, 10, 50, 20];
var fun = function(n) {
console.log("Before Promise => n: " n);
return new Promise(resolve => {
console.log("After Promise => n: " n);
setTimeout(() => {
console.log("Promise Resolved => n: " n);
resolve(0);
}, n * 30);
});
}
arr.reduce((p, v) => p.then(fun(v)), Promise.resolve(0));
1. Пожалуйста, поправьте меня, если я ошибаюсь, это Array.reduce()
уменьшит вышеуказанное в следующей Promise
цепочке:
Promise.resolve(0).then(fun(30)).then(fun(40)).then(fun(10)).then(fun(50)).then(fun(20)).
2. Почему вывод не такой, как показано ниже:
Promise Resolved => n: 30
Promise Resolved => n: 40
Promise Resolved => n: 10
Promise Resolved => n: 50
Promise Resolved => n: 20
3. И почему результат такой, как указано выше, если я изменяю, n*30
скажем, с фиксированным временем 500
?
Ответ №1:
.then
принимает функцию в качестве параметра, но вы делаете:
p.then(fun(v))
Это вызывает fun
немедленно, не дожидаясь p
разрешения, и передает возвращенное обещание .then
. Это похоже на выполнение
Promise.then(Promise.resolve(6))
// ^^^ but .then only accepts a function as a parameter
в этом нет никакого смысла.
Измените на обратный вызов, который при вызове вызывает fun
и возвращает fun
обещание:
var arr = [30, 40, 10, 50, 20];
var fun = function(n) {
console.log("Before Promise => n: " n);
return new Promise(resolve => {
console.log("After Promise => n: " n);
setTimeout(() => {
console.log("Promise Resolved => n: " n);
resolve(0);
}, n*30);
});
}
arr.reduce((p, v) => p.then(() => fun(v)), Promise.resolve(0));
// ^^^^^^
Ответ №2:
Array.reduce()
уменьшит вышеуказанное как следующую цепочку обещаний
ДА.
Почему результат не соответствует ожиданиям?
Потому что «цепочка» обещаний нарушена. Для правильной цепочки вам необходимо передать функции обратного вызова в then
:
Promise.resolve(0).then(() => fun(30)).then(() => fun(40)).then(() => fun(10)).then(() => fun(50)).then(() => fun(20));
// ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^
Сделайте то же самое в своем редукторе:
arr.reduce((p, v) => p.then(() => fun(v)), Promise.resolve(0));