async function
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2017.
Объявление async function
определяет асинхронную функцию, которая возвращает объект AsyncFunction
.
Вы также можете определить async-функции, используя выражение async function
.
Синтаксис
async function name([param[, param[, ... param]]]) { statements }
name
-
Имя функции.
param
-
Имя аргумента, который будет передан в функцию.
statements
-
Выражение, содержащее тело функции.
Описание
После вызова функция async
возвращает Promise
. Когда результат был получен, Promise
завершается, возвращая полученное значение. Когда функция async
выбрасывает исключение, Promise
ответит отказом с выброшенным (throws
) значением.
Функция async может содержать выражение await
, которое приостанавливает выполнение функции async и ожидает ответа от переданного Promise
, затем возобновляя выполнение функции async
и возвращая полученное значение.
Ключевое слово await
допустимо только в асинхронных функциях. В другом контексте вы получите ошибку SyntaxError
.
Примечание:
Цель функций async/await упростить использование promises синхронно и воспроизвести некоторое действие над группой Promises
. Точно так же как Promises
подобны структурированным колбэкам, async/await подобна комбинации генераторов и promises.
Примеры
Простой пример
function resolveAfter2Seconds(x) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(x);
}, 2000);
});
}
async function add1(x) {
const a = await resolveAfter2Seconds(20);
const b = await resolveAfter2Seconds(30);
return x + a + b;
}
add1(10).then((v) => {
console.log(v); // prints 60 after 4 seconds.
});
async function add2(x) {
const a = resolveAfter2Seconds(20);
const b = resolveAfter2Seconds(30);
return x + (await a) + (await b);
}
add2(10).then((v) => {
console.log(v); // prints 60 after 2 seconds.
});
Предупреждение:
Не путайте await и Promise.allФункция add1
приостанавливается на 2 секунды для первого await
и ещё на 2 для второго. Второй таймер создаётся только после срабатывания первого. В функции add2
создаются оба и оба же переходят в состояние await
. В результате функция add2
завершится скорее через две, чем через четыре секунды, поскольку таймеры работают одновременно. Однако запускаются они всё же не параллельно, а друг за другом - такая конструкция не означает автоматического использования Promise.all
. Если два или более Promise должны разрешаться параллельно, следует использовать Promise.all
.
Когда функция async
выбрасывает исключение
async function throwsValue() {
throw new Error("oops");
}
throwsValue().then(
(resolve) => {
console.log("resolve:" + resolve);
},
(reject) => {
console.log("reject:" + reject);
},
);
//prints "reject:Error: oops"
//or
throwsValue()
.then((resolve) => {
console.log("resolve:" + resolve);
})
.catch((reject) => {
console.log("reject:" + reject);
});
//prints "reject:Error: oops"
Перепись цепочки promise с использованием функции async
API, которое возвращает Promise
, будет возвращать значение в цепочке, тем самым разбивая функцию на много частей. Рассматривая следующий код:
function getProcessedData(url) {
return downloadData(url) // returns a promise
.catch((e) => {
return downloadFallbackData(url); // returns a promise
})
.then((v) => {
return processDataInWorker(v); // returns a promise
});
}
он может быть переписан с одним использованием функции async
:
async function getProcessedData(url) {
let v;
try {
v = await downloadData(url);
} catch (e) {
v = await downloadFallbackData(url);
}
return processDataInWorker(v);
}
Заметьте, что пример выше не содержит await
на return
, потому что возвращаемое значение функции async
неявно обёрнуто в Promise.resolve
.
Спецификации
Specification |
---|
ECMAScript Language Specification # sec-async-function-definitions |
Совместимость с браузерами
BCD tables only load in the browser