#javascript
#javascript
Вопрос:
Учитывая следующую функцию:
function makeTimeout(delay=3000) {
return new Promise(resolve => {
setTimeout(() => {
console.log(`I delayed for ${delay} seconds`);
resolve(`I delayed for ${delay} seconds`)
}, delay)
})
}
когда я запускаю makeTimeout(5000).then(makeTimeout(6000)).then(makeTimeout(200));
,
Я возвращаюсь:
I delayed for 200 seconds
I delayed for 5000 seconds
I delayed for 6000 seconds
разве это не должно происходить последовательно, а 200
второе — в конце?
Комментарии:
1. Нет, потому что вы делаете все тайм-ауты в начале, а затем передаете результаты как
.then
«обратные вызовы».2. результат
makeTimeout(6000)
не является функцией (и это ЕДИНСТВЕННОЕ . затем принимает)… он вызывает функцию
Ответ №1:
Вы вызываете последние два makeTimeout
s немедленно, в то время как интерпретатор находится в процессе построения цепочки обещаний. Вместо этого передайте обратные .then
вызовы, которые возвращают новое обещание:
makeTimeout(5000)
.then(() => makeTimeout(6000))
.then(() => makeTimeout(200));
Живой фрагмент:
function makeTimeout(delay=300) {
return new Promise(resolve => {
setTimeout(() => {
console.log(`I delayed for ${delay} seconds`);
resolve(`I delayed for ${delay} seconds`)
}, delay)
})
}
makeTimeout(500)
.then(() => makeTimeout(600))
.then(() => makeTimeout(20));
Комментарии:
1. Спасибо! принял ваш ответ и опубликовал ответ, но вопрос о том, что он работает по-другому при перемещении его в многострочный. Если я должен удалить его, пожалуйста, дайте мне знать
2. В большинстве случаев пробелы не имеют значения, они должны работать нормально с пробелами или без них — см. Фрагмент. Я просто сделал его многострочным для удобства чтения
Ответ №2:
.then
принимает два аргумента, (onResolved, onRejected)
оба должны быть функциями.
makeTimeout(100)
вызывается немедленно и возвращает a Promise
, а не a Function
Передача чего-то другого не является ошибкой .then
, поскольку, во-первых, так .catch
работает — в большинстве библиотек promise .catch(onReject)
is просто .then(null, onReject)
— .then
просто игнорирует аргументы, которые не являются функциями, не нарушая цепочку
т. е.
Promise.resolve(1)
.then(null, null)
.then(console.log, console.error)
или
Promise.reject(1)
.then(null, null)
.then(console.log, console.error)
Будет работать так, как будто .then(null, null)
его просто нет
Для полноты картины вы также можете изменить makeTimeout
, чтобы возвращать функцию, поскольку .then
игнорирует любой аргумент, который не является функцией
примечание: дополнительные ()
в makeTimeout(5000)().then
Это так же справедливо, хотя я бы не стал использовать такой шаблон для такого простого кода
function makeTimeout(delay=3000) {
return () => new Promise(resolve => {
setTimeout(() => {
console.log(`I delayed for ${delay} seconds`);
resolve(`I delayed for ${delay} seconds`)
}, delay)
})
}
makeTimeout(5000)().then(makeTimeout(6000)).then(makeTimeout(200));
Ответ №3:
Я попробовал это, и теперь это работает:
makeTimeout(5000)
.then(() => makeTimeout(6000))
.then(() => makeTimeout(200));
но разделение на несколько строк выводит их из строя…почему это?
makeTimeout(5000)
.then(() => {
makeTimeout(6000)
})
.then(() => {
makeTimeout(200)
});
Комментарии:
1. потому что во втором коде вы не возвращаете обещание, которое разрешается после задержки —
() => statement
это НЕ то же самое, что() => { statement; }
— это то же самое, что() => { return statement; }
2. о, в однострочном синтаксисе есть неявный возврат … извините