async & await
系列文章
这是JavaScript
系列文章:
async
异步函数语句
async function
简介
定义一个返回 AsyncFunction
对象的异步函数。
async
函数内并不一定要有await
,但是若存在await
, 则会等待await
执行完毕的回调函数,再继续往下执行。
注意,
await
只能出现在async
函数内,否则会报错。
基础语法
async function name([params, [params, []]]) { statements }
- name 函数名
- params 参数
- statements 函数体语句
示例
-
基础示例一
function resolveAfter2Seconds() { return new Promise(resolve => { setTimeout(() => { resolve('resolved'); }, 2000); }); } async function asyncCall() { console.log('calling'); let result = await resolveAfter2Seconds(); console.log(result); // expected output: resolved } asyncCall();
-
示例二:使用
async
重构 promise-
promise代码:
function getProcessedData(url) { return downloadData(url) // 返回一个Promise对象 .catch(e => { return downloadFallbackData(url); // 返回一个Promise对象 }) .then(v => { return processDataInWorker(v); // 返回一个Promise对象 }); }
-
async重构代码:
为了避免await报错,所以这里使用try...catch
来避免错误。async function getProcessedData(url) { let v; try { v = await downloadData(url); } catch (e) { v = await downloadFallbackData(url); } return processDataInWorker(v); }
-
-
示例三: 复杂示例
var resolveAfter2Seconds = function() { console.log("starting slow promise"); return new Promise(resolve => { setTimeout(function() { resolve("slow"); console.log("slow promise is done"); }, 2000); }); }; var resolveAfter1Second = function() { console.log("starting fast promise"); return new Promise(resolve => { setTimeout(function() { resolve("fast"); console.log("fast promise is done"); }, 1000); }); }; var sequentialStart = async function() { console.log('==SEQUENTIAL START=='); // 1. Execution gets here almost instantly const slow = await resolveAfter2Seconds(); console.log(slow); // 2. this runs 2 seconds after 1. const fast = await resolveAfter1Second(); console.log(fast); // 3. this runs 3 seconds after 1. } var concurrentStart = async function() { console.log('==CONCURRENT START with await=='); const slow = resolveAfter2Seconds(); // starts timer immediately const fast = resolveAfter1Second(); // starts timer immediately // 1. Execution gets here almost instantly console.log(await slow); // 2. this runs 2 seconds after 1. console.log(await fast); // 3. this runs 2 seconds after 1., immediately after 2., since fast is already resolved } var concurrentPromise = function() { console.log('==CONCURRENT START with Promise.all=='); return Promise.all([resolveAfter2Seconds(), resolveAfter1Second()]).then((messages) => { console.log(messages[0]); // slow console.log(messages[1]); // fast }); } var parallel = async function() { console.log('==PARALLEL with await Promise.all=='); // Start 2 "jobs" in parallel and wait for both of them to complete await Promise.all([ (async()=>console.log(await resolveAfter2Seconds()))(), (async()=>console.log(await resolveAfter1Second()))() ]); } // This function does not handle errors. See warning below! var parallelPromise = function() { console.log('==PARALLEL with Promise.then=='); resolveAfter2Seconds().then((message)=>console.log(message)); resolveAfter1Second().then((message)=>console.log(message)); } sequentialStart(); // after 2 seconds, logs "slow", then after 1 more second, "fast" // wait above to finish setTimeout(concurrentStart, 4000); // after 2 seconds, logs "slow" and then "fast" // wait again setTimeout(concurrentPromise, 7000); // same as concurrentStart // wait again setTimeout(parallel, 10000); // truly parallel: after 1 second, logs "fast", then after 1 more second, "slow" // wait again setTimeout(parallelPromise, 13000); // same as parallel
const xxx = await resolveFunction();
-
const xxx = resolveFunction();` console.log(await xxx);
- 执行多个await函数
return Promise.all([resolveAfter2Seconds(), resolveAfter1Second()]).then((messages) => { console.log(messages[0]); // slow console.log(messages[1]); // fast });
- 同三,执行多个await函数,但是另一种写法
await Promise.all([ (async()=>console.log(await resolveAfter2Seconds()))(), (async()=>console.log(await resolveAfter1Second()))() ]);
resolveAfter2Seconds().then((message)=>console.log(message));
异步函数表达式
async function expression
异步函数语句 与 异步函数表达式 区别:
1. 异步函数表达式可以忽略函数名,创建一个匿名函数
2. 异步函数表达式可以立即执行
示例:
function resolveAfter2Seconds(x) {
return new Promise(resolve => {
setTimeout(() => {
resolve(x);
}, 2000);
});
}
let add1 = async function(x) {
let a = await resolveAfter2Seconds(20);
let b = await resolveAfter2Seconds(30);
return x + a + b;
}
add1(10).then(v => {
console.log(v);
});
// async function express
(async function(x) {
let p_a = resolveAfter2Seconds(20);
let p_b = resolveAfter2Seconds(30);
return x + await p_a + await p_b;
})(10).then(v => {
console.log(v);
});
await
-
简介
await
用于等待一个Promise
对象,且只能在async function
中使用。await
会暂停当前函数执行,直到Promise执行完毕。然后继续往下执行。
-
基础语法
[return_value] = await expression;
-
示例:若Promise处理异常,则异常值被抛出
async function f3() { try { var z = await Promise.reject(30); } catch (e) { console.log(e); // 30 } } f3();
小技巧
多个promise如何并行执行
- Promise.all
async function test1() { const [resA, resB] = await Promise.all([ funcPromiseA(), funcPromiseB() ]); }
- 分两步写
async function test() { let promiseA = funcPromiseA(); let promiseB = funcPromiseB(); let resA = await promiseA; let resB = await promiseB; }
for循环中使用await
async function test2() {
let req = ['a', 'b'];
const promises = req.map(item => otherFunc(item));
for (const promiseItem of promises) {
const res = await promiseItem;
}
}
参考链接
[1] MDN, async function
[2] MDN, async function expression
[3] MDN, AsyncFunction
[4] MDN, await
[5] 阮一峰, async 函数
感谢