предисловие
js имеет множество решений для асинхронной обработки, в то время какasync/await
Это один из них.В последнее время я изучаю и использую koa.На стороне сервера обещания используются редко, но выбираются более элегантные.async/await
. Конечно, когда появляется новое решение, нужно не только научиться писать, но и изучить его принципы.
Что делает async/await?
async/await
Буквально хорошо понял,async
значит асинхронный.await
Оно имеет значение ожидания, и то же самое верно в использовании обоих.async
объявитьfunction
является асинхронным, в то время какawait
Используется для ожидания завершения выполнения асинхронного метода.
async
Синтаксис async очень прост, достаточно добавить ключевое слово в начало функции, например:
async function f() {
return 1;
}
Значение ключевого слова async очень простое, то есть функция возвращает обещание.
async function f() {
return 1;
}
f().then((res) => {
console.log(res)
}) // 1
Асинхронная функция вернет объект обещания. Если функция возвращает значение, асинхронная будет напрямую использоватьPromise.resolve()
Упакуйте обратно.
await
Ключевые слова ждать ждать означало, чего же тогда он ждет? MDN написано на:
[return_value] = await expression;
Ожидается выражение, тогда выражение может быть константой, переменной, промисом, функцией и т. д.
function getSomething() {
return "something";
}
async function testAsync() {
return Promise.resolve("hello async");
}
async function test() {
const v1 = await getSomething();
const v2 = await testAsync();
console.log(v1, v2);
}
test(); // something hello async
- Почему ключевое слово await можно использовать только в асинхронных функциях
Оператор await ожидает возвращаемого результата, поэтому, если он синхронный, он возвращается напрямую.
Если он асинхронный, то в случае асинхронного await заблокирует весь процесс, и следующий код не будет продолжаться до тех пор, пока не будет возвращен результат.
Блокирующий код — ужасная вещь, а асинхронные функции будут завернуты в промис и выполняться асинхронно. Следовательно, await можно использовать только в асинхронных функциях, если его использовать в обычной программе, это приведет к блокировке всей программы, что не стоит потерь.
Обработка ошибок в async/await
Обещание — это не только один из видов решимости, но и один из видов отказа. А await только ждет результата, так что мне делать, если возникает ошибка?
- Ошибка перехвата с помощью try-catch
async function myFunction() {
try {
await Promise.reject('1');
} catch (err) {
console.log(err);
}
}
myFunction(); // 1
- Используйте улов обещания, чтобы поймать ошибку
async function myFunction() {
await Promise.reject('1').catch((err) => {
console.log(err);
});
}
myFunction(); // 1
Разница между async/await и обещанием
Самая большая проблема с промисами в том, что после усложнения бизнеса внутренняя логика потом тоже усложняется, либо не так красиво будут написаны асинхронные сценарии вложенности циклов и т.д.
Я произвольно привожу вложенный пример, а затем используюasync/await
а такжеpromise
, вы можете почувствовать разницу между ними:
function takeLongTime(n) {
return new Promise(resolve => {
setTimeout(() => resolve(n), n);
});
}
function step1(n) {
console.log(`step1 with ${n}`);
return takeLongTime(n);
}
function step2(m, n) {
console.log(`step2 with ${m} and ${n}`);
return takeLongTime(m + n);
}
function step3(k, m, n) {
console.log(`step3 with ${k}, ${m} and ${n}`);
return takeLongTime(k + m + n);
}
Функция takeLongTime заключается в предоставлении задержанных данных после задержки.
step1 представляет, как долго первый шаг задерживается.
step2 представляет общую задержку первого и второго шагов.
step3 показывает, как долго были задержаны первый, второй и третий шаги.
- обещанная версия
function doIt() {
console.time("doIt");
const time1 = 300;
step1(time1)
.then(time2 => {
return step2(time1, time2)
.then(time3 => [time1, time2, time3]);
})
.then(times => {
const [time1, time2, time3] = times;
return step3(time1, time2, time3);
})
.then(result => {
console.log(`result is ${result}`);
console.timeEnd("doIt");
});
}
doIt();
- асинхронная/ждущая версия
async function doIt() {
console.time("doIt");
const time1 = 300;
const time2 = await step1(time1);
const time3 = await step2(time1, time2);
const result = await step3(time1, time2, time3);
console.log(`result is ${result}`);
console.timeEnd("doIt");
}
doIt();
В этой сложной логике мы можем найтиasync/await
У него есть преимущества перед цепями.
Суммировать
Async/await — асинхронное решение, и koa поддерживает эту возможность, поэтому при написании серверного кода на основе koa этот синтаксический сахар неизбежен, его изучение и использование — наш обязательный курс.