全手打原创,转载请标明出处:http://www.javashuo.com/article/p-dpxcddwt-gr.html,多谢,=。=~html
抛出3个疑问:express
一、async是干哈的?异步
二、await在等啥?async
三、await等到了又要干哈?函数
先说说AsyncFunctionspa
AsyncFunction构造函数用来建立新的异步函数对象,JavaScript中每一个异步函数都是AsyncFunction的对象。线程
new AsyncFunction([arg1[, arg2[, ...argN]],] functionBody)
arg1, arg2, ... argN:函数参数名,一个或多个用逗号隔开的字符串;code
functionBody:一段字符串形式的 JavaScript 语句,这些语句组成了新函数的定义;htm
function resolveAfter2Seconds(x) { return new Promise(resolve => { setTimeout(() => { resolve(x); }, 2000); }); } var AsyncFunction = Object.getPrototypeOf(async function(){}).constructor; var a = new AsyncFunction('a', 'b', 'return await resolveAfter2Seconds(a) + await resolveAfter2Seconds(b);'); a(10, 20).then(v => { console.log(v); // 4 秒后打印 30 });
注:AsyncFunction非全局对象,因此须要经过 Object.getPrototypeOf(async function(){}).constructor 获取对象
先说明AsyncFunction的缘由是执行 AsyncFunction 构造函数时,能够建立一个异步函数对象。可是这种方式不如先用异步函数表达式(也就是async function)定义一个异步函数,而后再调用它来建立异步函数对象来的高效,由于第二种方式中异步函数是与其余代码一块儿被解释器解析的,而第一种方式的函数体是单独解析的。能够跟下面async的例子对比查看。
接着上async定义+语法
带async关键字的函数,它使得你的函数返回值一定是Promise对象
不明白的能够在console中敲一下下面的代码:
async关键字使用分为异步函数表达式和异步函数语句,二者很是类似,语法也基本相同。它们之间的主要区别在于异步函数表达式能够省略函数名称来建立一个匿名函数。另外,异步函数表达式还能够用在 IIFE (当即执行函数表达式,Immediately Invoked Function Expression) 中。
一、异步函数表达式
async function [name]([param1[, param2[, ..., paramN]]]) { statements }
name:此异步函数的名称,可省略。若是省略则这个函数将成为匿名函数。该名称仅可在本函数中使用。
function resolveAfter2Seconds(x) { return new Promise(resolve => { setTimeout(() => { resolve(x); }, 2000); }); }; // async function expression assigned to a variable var add1 = async function(x) { var a = await resolveAfter2Seconds(20); var b = await resolveAfter2Seconds(30); return x + a + b; } add1(10).then(v => { console.log(v); // 4 秒后打印 60 }); (async function(x) { // async function expression used as an IIFE var p_a = resolveAfter2Seconds(20); var p_b = resolveAfter2Seconds(30); return x + await p_a + await p_b; })(10).then(v => { console.log(v); // 2 秒后打印 60 });
二、异步函数语句
async function name([param[, param[, ... param]]]) { statements }
name:函数名称
function resolveAfter2Seconds() { return new Promise(resolve => { setTimeout(() => { resolve('resolved'); }, 2000); }); } async function asyncCall() { console.log('calling'); var result = await resolveAfter2Seconds(); console.log(result); // expected output: 'resolved' } asyncCall();
执行顺序:
(1)异步函数能够包含await指令,该指令会暂停原异步函数的执行,并等待右侧Promise返回结果;
(2)当异步函数暂停时,await右侧调用的函数会继续执行(收到异步函数返回的隐式Promise);
而后上await定义+语法
用于等待右侧表达式的结果(先执行右侧表达式再让出线程阻塞代码,若右侧为同步直接执行,若为异步会等待外部同步代码执行完毕)。它只能在异步函数 async function 中使用。
[return_value] = await expression
Expression:一个 Promise 对象或者任何要等待的值;
return_value:返回 Promise 对象的处理结果;若是等待的不是 Promise 对象,则返回该值自己;
执行顺序:
(1)await 表达式会暂停当前 async function 的执行,等待 Promise 处理完成;
(2)若 Promise 正常处理(Resolved,又称Fulfilled),其回调resolve函数的参数做为 await 表达式的值,继续执行 async function;
(3)若 Promise 处理异常(Rejected),await 表达式会把 Promise 的异常缘由抛出;
解决开头的3个疑问:
一、async是干哈的?
定义异步函数(内部一般有异步操做),返回Promise对象(函数返回Promise→显式返回return的Promise;函数返回非Promise→隐式返回Promise.resolve()包装的return值;)
二、await在等啥?
只能放在async函数中,等待右侧表达式结果(函数→结果=return值;字符串→结果=字符串;)
三、await等到了又要干哈?
阻塞后面的代码,先执行async外部的同步代码,同步代码执行完再回到async内部,拿到运算结果(表达式返回Promise→等待Promise对象fulfilled,再将resolve参数做为表达式的运算结果;表达式返回非Promise→直接做为表达式的运算结果;)
参考资料:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference