js之async和await

async/await 是一种编写异步代码的新方法,之前异步代码的方案是回调和 promise,但async/await建立在promise基础上。
async和await是ES7中与异步操作有关的关键字。

async

async function name([param[, param[, ... param]]]) { statements }
async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数。如果在函数中 return 一个直接量,async 会把这个直接量通过 Promise.resolve() 封装成 Promise 对象。

async function testAsync() {
 return "hello async";
}

let result = testAsync();
console.log(result)
// Promise {<resolved>: "hello async"}

await 关键字仅在 async function 中有效。如果在 async function 函数体外使用 await ,会得到一个语法错误。

await

[return_value] = await expression;
expression: 一个 Promise 对象或者任何要等待的值。
await针对所跟不同表达式的处理方式:
Promise对象:await 会暂停执行,等待 Promise 对象 resolve(异步操作完成),然后恢复 async 函数的执行并返回解析值。
非Promise对象:直接返回对应的值。

function testAwait (x) {
return new Promise(resolve => {
setTimeout(() => {
resolve(x);
}, 2000);
});
}

async function helloAsync() {
var x = await testAwait ("hello world");
console.log(x); 
}
helloAsync ();
// hello world

很多人以为await会一直等待之后的表达式执行完之后才会继续执行后面的代码,实际上await是一个让出线程的标志

await后面的函数会先执行一遍,然后就会跳出整个async函数来执行后面js栈(后面会详述)的代码。等本轮事件循环执行完了之后又会跳回到async函数中等待await后面表达式的返回值,

如果返回值为非promise则继续执行async函数后面的代码,否则将返回的promise放入promise队列(Promise的Job Queue)。

以下摘自:Js中async/await的执行顺序详解

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

在testSomething前增加aync:

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();//关键点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...
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对象先推入队列。

posted @ 2020-07-12 14:07  yuxi_o  阅读(2188)  评论(0编辑  收藏  举报