随着async/await正式归入ES7标准,愈来愈多的人开始研究听说是异步编程终级解决方案的 async/await。可是不少人对这个方法中内部怎么执行的还不是很了解,本文是我看了一遍技术博客理解 JavaScript 的 async/await(若是对async/await不熟悉能够先看下这篇文章)后拓展了一下,我理了一下await以后js的执行顺序,但愿能够给别人解疑答惑,先简单介绍一下async/await。编程
async function testAsync() { return "hello async"; } let result = testAsync(); console.log(result)
输出结果:segmentfault
Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: "hello async"}
从结果中能够看到async函数返回的是一个promise对象,若是在函数中 return 一个直接量,async 会把这个直接量经过 Promise.resolve() 封装成 Promise 对象。promise
若是asyn函数没有返回值异步
async function testAsync1() { console.log("hello async"); } let result1 = testAsync1(); console.log(result1);
结果async
hello async Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: undefined}
结果返回Promise.resolve(undefined)。异步编程
从字面意思上看await就是等待,await 等待的是一个表达式,这个表达式的返回值能够是一个promise对象也能够是其余值。函数
不少人觉得await会一直等待以后的表达式执行完以后才会继续执行后面的代码,实际上await是一个让出线程的标志。await后面的函数会先执行一遍,而后就会跳出整个async函数来执行后面js栈(后面会详述)的代码。等本轮事件循环执行完了以后又会跳回到async函数中等待await
后面表达式的返回值,若是返回值为非promise则继续执行async函数后面的代码,不然将返回的promise放入promise队列(Promise的Job Queue)线程
先看一个例子code
function testSometing() { console.log("执行testSometing"); return "testSometing"; } async function testAsync() { console.log("执行testAsync"); return Promise.resolve("hello async"); } async function test() { console.log("test start..."); const v1 = await testSometing();//关键点1 console.log(v1); const v2 = await testAsync(); console.log(v2); console.log(v1, v2); } test(); var promise = new Promise((resolve)=> { console.log("promise start.."); resolve("promise");});//关键点2 promise.then((val)=> console.log(val)); console.log("test end...")
输出结果:对象
test start... 执行testSometing promise start.. test end... testSometing 执行testAsync promise hello async testSometing hello async
当test函数执行到
const v1 = await testSometing();
的时候,会先执行testSometing这个函数打印出“执行testSometing”的字符串,而后由于await会让出线程就会区执行后面的
var promise = new Promise((resolve)=> { console.log("promise
start.."); resolve("promise");});//关键点2
而后打印出“promise start..”接下来会把返回的这promise放入promise队列(Promise的Job Queue),继续执行打印“test end...”,等本轮事件循环执行结束后,又会跳回到async函数中(test函数),等待以前await 后面表达式的返回值,由于testSometing 不是async函数,因此返回的是一个字符串“testSometing”,test函数继续执行,执行到
const v2 = await testAsync();
和以前同样又会跳出test函数,执行后续代码,此时事件循环就到了promise的队列,执行promise.then((val)=> console.log(val));
then后面的语句,以后和前面同样又跳回到test函数继续执行。
这个就是在async/await 函数以后js的执行顺序,咱们再看一个列子把testSometing函数前面加上async
async function testSometing() { console.log("执行testSometing"); return "testSometing"; } async function testAsync() { console.log("执行testAsync"); return Promise.resolve("hello async"); } async function test() { console.log("test start..."); const v1 = await testSometing(); console.log(v1); const v2 = await testAsync(); console.log(v2); console.log(v1, v2); } test(); var promise = new Promise((resolve)=> { console.log("promise start.."); resolve("promise");});//3 promise.then((val)=> console.log(val)); console.log("test end...")
输出结果:
test start... 执行testSometing promise start.. test end... promise testSometing 执行testAsync hello async testSometing hello async
和上一个例子比较发现promise.then((val)=> console.log(val));
先与console.log(v1);
执行了,缘由是由于如今testSometing函数加了async,返回的是一个Promise
对象要要等它resolve
,因此将当前Promise推入队列,因此会继续跳出test函数执行后续代码。以后就开始执行promise的任务队列了,因此先执行了promise.then((val)=> console.log(val));
由于这个Promise对象先推入队列;
写到这里你们应该已经清楚了使用async/await进行异步操做时js的执行顺序,在研究过程当中还发现了js的任务队列执行顺序的问题,就下次再述。若是你们对有什么意见或建议能够指出。本篇是我第一次发布文章,但愿你们不吝赐教。