async

async函数返回一个 Promise 对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。

function setNumAdd(n) {
return new Promise((resolve,reject) =>{
setTimeout( ()=>{
n +=1;
resolve(n)
},1000)
})
} function setNumSub(n) {
return new Promise((resolve,reject) =>{
setTimeout( ()=>{
n -=1;
resolve(n)
},1000)
})
} async function d(n) {
const w1 = await setNumAdd(n);
const w2 = await setNumSub(n);
return w1+w2
}
d(10).then( v=>{
console.log(v) //
})

async函数返回一个 Promise 对象。async函数内部return语句返回的值,会成为then方法回调函数的参数。

async function f() {
return 'hello world';
} f().then(v => console.log(v))
// "hello world"

async函数内部抛出错误,会导致返回的 Promise 对象变为reject状态。抛出的错误对象会被catch方法回调函数接收到。

async function f() {
throw new Error('出错了');
} f().then(
v => console.log(v),
e => console.log(e)
) //等同于 f().then( v=> console.log(v)).catch( e=>console.log(e))
// Error: 出错了

await

正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。

async function f() {
// 等同于
// return 123;
return await 123;
} f().then(v => console.log(v))
//

任何一个await语句后面的 Promise 对象变为reject状态,那么整个async函数都会中断执行。

async function f() {
await Promise.reject('出错了');
await Promise.resolve('hello world'); // 不会执行
}

上面代码中,第二个await语句是不会执行的,因为第一个await语句状态变成了reject

有时,我们希望即使前一个异步操作失败,也不要中断后面的异步操作。这时可以将第一个await放在try...catch结构里面,这样不管这个异步操作是否成功,第二个await都会执行。

async function f() {
try {
await Promise.reject('出错了');
} catch(e) {
}
return await Promise.resolve('hello world');
} f()
.then(v => console.log(v))
// hello world

另一种方法是await后面的 Promise 对象再跟一个catch方法,处理前面可能出现的错误

async function f() {
await Promise.reject('出错了')
.catch(e => console.log(e));
return await Promise.resolve('hello world');
} f()
.then(v => console.log(v))
// 出错了
// hello world
错误处理

如果有多个await命令,可以统一放在try...catch结构中。

async function main() {
try {
const val1 = await firstStep();
const val2 = await secondStep(val1);
const val3 = await thirdStep(val1, val2); console.log('Final: ', val3);
}
catch (err) {
console.error(err);
}
}
let foo = await getFoo();
let bar = await getBar();

多个await命令后面的异步操作,如果不存在继发关系,最好让它们同时触发。

上面代码中,getFoogetBar是两个独立的异步操作(即互不依赖),被写成继发关系。这样比较耗时,因为只有getFoo

完成以后,才会执行getBar,完全可以让它们同时触发。

// 写法一
let [foo, bar] = await Promise.all([getFoo(), getBar()]); // 写法二
let fooPromise = getFoo();
let barPromise = getBar();
let foo = await fooPromise;
let bar = await barPromise;

最新文章

  1. python笔记
  2. bzoj2702[SDOI2012]走迷宫
  3. Android高手速成--第三部分 优秀项目
  4. 基于服务(Web Service)的文件管理Winform客户端实现(二)
  5. SpringBoot之springfox(Swagger) (ApiDoc接口文档)
  6. Android Studio安装与配置
  7. SQL PROMPT 取消dbo前缀
  8. 浏览器中显示视频,flash等的代码处理
  9. tomcat虚拟主机虚拟目录配置
  10. 【UWP】列表项宽度自适应的实现
  11. LeetCode 90. Subsets II (子集合之二)
  12. Linux 学习记录 三(Vim 文书编辑器).
  13. 网络通信 --> IO多路复用之select、poll、epoll详解
  14. javabean 是什么?
  15. gojs常用API-画布定义
  16. SpringCloud Gateway 测试问题解决
  17. 雷林鹏分享:jQuery EasyUI 数据网格 - 动态改变列
  18. Day20--Python--约束和异常处理
  19. rest_framework的认证系统
  20. C# Bitmap长宽参数构造的图片对象的每个像素ARGB都是0

热门文章

  1. 用StatSVN统计svn项目中每人代码提交量
  2. IDEA自动清理优化import包
  3. 【转载】PC端微信设置操作快捷键方法
  4. js 取得数组中的最大值和最小值(含多维数组)
  5. selenium三个等待方法
  6. Java集合框架总结2_Map
  7. maven学习笔记四(聚合和继承)
  8. 【CMDB】API传输验证
  9. ELK Stack部署
  10. SQL进阶系列之8EXISTS谓词的用法