js async/await
一、async
带async关键字的函数,是声明异步函数,返回值是promise对象,如果async关键字函数返回的不是promise,会自动用Promise.resolve()包装。
async function test() {
return 'test'
}
test();
返回值为 Promise {<resolved>: "test"}。
二、await
await等待右侧表达式的结果,这个结果是promise对象或者其他值。
如果它等到的不是一个 promise 对象,那 await 表达式的运算结果就是它等到的东西。
如果它等到的是一个 promise 对象,await 就忙起来了,它会阻塞后面的代码,等着 promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。
function test() {
return new Promise(resolve => {
setTimeout(() => resolve("test"), );
});
}
const result = await test();
console.log(result);
console.log('end')
由于test()造成的阻塞,console.log('end')会等到两秒后执行
所以为了避免造成阻塞,await 必须用在 async 函数中,async 函数调用不会造成阻塞。
function test() {
return new Promise(resolve => {
setTimeout(() => resolve("test"), );
});
}
async function test2() {
const result = await test();
console.log(result);
}
test2();
console.log('end');
先执行console.log('end'),两秒后执行console.log('test')
如果await用在普通函数中,会报错,如下:

三、async/await的执行顺序
遇到await会阻塞后面的代码,先执行async外面的同步代码,同步代码执行完,再回到async内部,继续执行await后面的代码。以下面的代码分析:
async function test1() {
console.log('start test1');
console.log(await test2());
console.log('end test1');
}
async function test2() {
console.log('test2');
return await 'return test2 value'
}
test1();
console.log('start async');
setTimeout(() => {
console.log('setTimeout');
}, );
new Promise((resolve, reject) => {
console.log('promise1');
resolve();
}).then(() => {
console.log('promise2');
});
console.log('end async');
执行的结果

· 首先执行宏任务,执行test1函数,执行console.log('statr test1')
· 遇到await,先执行右边test2中的console.log('test2'),中断了后面的代码,执行test1外面的同步代码
· 执行console.log('start async');
· 遇到setTimeout,推到到下个宏任务队列中
· 执行Promise里面的同步代码console.log('promise1')
· 运行到promise().then,发现是promise对象,推到微任务队列中
· 执行console.log('end async')
· test1外面的同步代码执行结束后,回到test1中,console.log(await test2())执行完成后返回Promise {<resolved>: "return test2 value"},是promise对象,推到微任务队列中
· 此时第一个宏任务结束,执行所有的微任务,因为微任务队列先进先出,所以先执行console.log('promise2'),后执行console.log('return test2 value')
· 执行test2完成后,后面的代码不再阻塞,执行console.log('end test1');
· 执行下个宏任务,即执行console.log('setTimeout');
补充下有关宏任务和微任务的知识
宏任务和微任务都是队列,宏任务有script、setTimeout、setInterval等,微任务有Promise.then catch finally、process.nextTick等,宏任务和微任务的关系如下:

先执行第一个宏任务,执行结束后,执行所有的微任务,然后执行下个宏任务。
四、async/await的优缺点
1. 优点
相对于promise,async/await处理 then 的调用链,代码要清晰很多,几乎和同步代码一样
2. 缺点
滥用 await 可能会导致性能问题,因为 await 会阻塞代码
五、处理reject
1. try/catch
async function fn() {
try {
await new Promise((resolve, reject) => {
setTimeout(() => {
reject('err3');
}, );
})
} catch (err){
alert(err)
}
}
fn()
2. catch
async function fn() {
await new Promise((resolve, reject) => {
setTimeout(() => {
reject('err');
}, );
})
}
fn().catch(alert)
参考:
1. https://segmentfault.com/a/1190000007535316
2. https://segmentfault.com/a/1190000017224799
3. https://www.cnblogs.com/wangziye/p/9566454.html
js async/await的更多相关文章
- js async await 终极异步解决方案
既然有了promise 为什么还要有async await ? 当然是promise 也不是完美的异步解决方案,而 async await 的写法看起来更加简单且容易理解. 回顾 Promise Pr ...
- node.js async/await 继发执行与并发执行
async/await 继发执行与并发执行,看如何控制 两个异步函数 foo bar function foo() { return new Promise((resolve, reject) =&g ...
- [转] js async await 终极异步解决方案
阅读目录 回顾 Promise async await 字面理解 async.await 如何执行 await 操作符 总结 既然有了promise 为什么还要有async await ? 当然是pr ...
- [node.js] async/await如何优雅处理异常?
node.js的世界,从callback开始,不会止于async. 所有人都在骂为什么不能完全进化,其实我感觉这就是老外的细心,为了承上.这也就是为什么async其实就是promise一样,假如不是一 ...
- 图与例解读Async/Await
JavaScript ES7的async/await语法让异步promise操作起来更方便.如果你需要从多个数据库或者接口按顺序异步获取数据,你可能最终写出一坨纠缠不清的promise与回调.然而使用 ...
- js异步编程终级解决方案 async/await
在最新的ES7(ES2017)中提出的前端异步特性:async.await. async.await是什么 async顾名思义是“异步”的意思,async用于声明一个函数是异步的.而await从字 ...
- callback vs async.js vs promise vs async / await
需求: A.依次读取 A|B|C 三个文件,如果有失败,则立即终止. B.同时读取 A|B|C 三个文件,如果有失败,则立即终止. 一.callback 需求A: let read = functio ...
- 【学习笔记】JS经典异步操作,从闭包到async/await
参考文献:王仕军——知乎专栏前端周刊 感谢作者的热心总结,本文在理解的基础上,根据自己能力水平作了一点小小的修改,在加深自己印象的同时也希望能和各位共同进步... 1. 异步与for循环 抛出一个问题 ...
- JS异步编程 (2) - Promise、Generator、async/await
JS异步编程 (2) - Promise.Generator.async/await 上篇文章我们讲了下JS异步编程的相关知识,比如什么是异步,为什么要使用异步编程以及在浏览器中JS如何实现异步的.最 ...
随机推荐
- Delphi 实现检测线程类TThread是否结束
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...
- MVC中使用showModalDialog
1.mvc中使用模态对话框用于修改数据,如果第一次修改过后刷新页面,第二次修改时显示内容依然是第一次修改之前的,这里用js中的Math.Random()解决 Views: <%: Html.Ac ...
- Educational Codeforces Round 30D. Merge Sort
归并排序的逆操作,每次二分时把第二段第一位与第一段最后一位开始往前第一个比它大的数交换位置 可以用归并排序验证答案对不对 #include<bits/stdc++.h> #define f ...
- cout是右结合的
cout是右结合的,(从右到左压栈?) cout<<++a<<","<<a++; 的运行顺序是 1.a的值压栈 2.a自加 3.‘,’压栈 4 ...
- appium-环境搭建(三)
appium步骤:基本环境1.由于操作手机端操作,需要模拟器或者真机 itools模拟器,真机2.appium操作app,需要知道操作的app是什么?需要知道这个app包名 1.问开发 2.利用adt ...
- codeforces 589G G. Hiring(树状数组+二分)
题目链接: G. Hiring time limit per test 4 seconds memory limit per test 512 megabytes input standard inp ...
- codeforces 655D D. Robot Rapping Results Report(拓扑排序+拓扑序记录)
题目链接: D. Robot Rapping Results Report time limit per test 2 seconds memory limit per test 256 megaby ...
- 影响Cache的几个HTTP头信息【转载http://hi.baidu.com/feilala_fly/item/f79eca08fbf389026c9048a7】
Http的Cache机制总共有4个组成部分: Cache-Control.Last-Modified(If-Modified-Since).Etag(If-None-Match) .Expires 服 ...
- BZOJ1033:[ZJOI2008]杀蚂蚁
我对模拟的理解:https://www.cnblogs.com/AKMer/p/9064018.html 题目传送门:https://www.lydsy.com/JudgeOnline/problem ...
- fiddler 的AutoRespoder的使用(手动添加测试桩)
---恢复内容开始--- 1.首先我们抓取一个百度的请求,由于百度请求是https协议,需要手动添加证书(这个不写了,大佬们自己手动找下资料) 2.fiddler抓取的百度请求,其他的无关信息删除,便 ...