#javascript #asynchronous #promise #async-await #es6-promise
#javascript #асинхронный #обещание #async-await #es6-обещание
Вопрос:
Я пытаюсь вернуть некоторые тестовые данные из метода, который вызывает rest api. Чтобы имитировать вызов rest api, я добавляю некоторую задержку для возврата обещания с использованием шаблона async-await, но он работает не так, как ожидалось.
Мое понимание шаблона async-await в JavaScript заключается в том, что любое значение, возвращаемое из асинхронной функции, возвращается как обещание, поэтому значение 100 должно быть возвращено функцией как обещание, и поэтому последний оператор, использующий .then
, должен показывать 100, но это не так.
Вопрос, что не так с приведенным ниже фрагментом кода, из-за которого отображается предупреждение в последней строке кода, undefined
а не 100?
async function f() {
function delayedResponse() {
setTimeout(function() { return 100}, 5000);
}
return await delayedResponse();
}
f().then(alert); // 100
Комментарии:
1.
delayedResponse
ничего не возвращает ->undefined
2. Если нет явного
Promise
, возвращаемое значение будет автоматически обернуто вPromise
. Если вы хотите «вернуть» что-то изsetTimeout
обратного вызова, вы должны использовать aPromise
и разрешить его в обратном вызове.3. ОК. Теперь я понял. Я должен использовать объект Promise. У меня сложилось впечатление, что я мог бы просто использовать async await без обещания, но теперь это ясно. Спасибо.
Ответ №1:
Вы ничего не возвращаете в своем delayedResponse
, поэтому это привело undefined
.
Вместо этого, чтобы достичь того, чего вы ожидаете, вы можете явно создать обещание и разрешить значение, используя тайм-аут;
async function f() {
return new Promise(resolve => {
setTimeout(function() { resolve(100)}, 5000);
});
}
f().then(alert); // 100
Комментарии:
1. К вашему сведению, вы можете сделать
setTimeout(resolve, 5000, 100);
вместо объявления отдельной функции обратного вызова дляsetTimeout(function() { resolve(100)}, 5000);
.2. @jfriend00 точно!
Ответ №2:
NodeJS 14.x или API браузера
async function delay(msecs: number) {
return new Promise((resolve) => setTimeout(resolve, msecs));
}
NodeJS 16.x или более поздней версии
import { setTimeout } from "timers/promises";
const result = await setTimeout(msecs, 'somevalue')
Обратите внимание, что порядок setTimeout()
аргументов изменился!
Старое setTimeout()
определено, если вы не импортируете из «таймеров / обещаний».
Ссылки