写点什么

重学 JS | 异步编程 async/await

用户头像
梁龙先森
关注
发布于: 2021 年 01 月 14 日
重学JS | 异步编程 async/await

async是 ES2017 推出的函数,也是异步编程的解决方案,字面是异步的意思,那么使用它就应该不会阻塞后面代码的执行。首先我们来看个日常用法:

// 例子1function wait(){	return new Promise((resolve,reject)=>{  	setTimeout(()=>{    	console.log('延迟1s')      resolve('我执行了')    },1000)  })}
async function run(){ console.log('开始') let p = await wait() console.log(p) console.log('结束')}
run()// 依次输出:// 开始// Promise<pending>// 我执行了// 延迟1s// 结束
复制代码

从例子中我们可以总结出:

  1. async关键字放在函数前,表示函数为异步函数

  2. await关键字是等待的意思,需要等后面的表达式执行结束,才往下走

  3. await关键字只能在async函数内部使用


知道了async/await的用法,看到单独使用async函数是什么效果。

// 例子2async function wait(){	return 'gogo'}wait()// 输出:Promise{[[PromiseStatus]]: "resolved",[[PromiseValue]]: "gogo"}
wait().then(res=>{ console.log(res) // 输出:gogo})
复制代码

可以看出async()函数返回的是Promise对象,而且Promise有个resolved。我们可以大胆推测,当async()函数有返回值时,会通过Promise.resolve()函数进行封装,返回一个Promise对象。同理,如果内部发生异常,则会使用Promsie.reject()函数进行封装返回。


这里结合例子 1 的写法,也可以看出,async函数返回的是Promise对象,要获取返回值可以使用await关键字,但需等待await后面表达式执行结束返回。


了解了Async函数的基础用法,那async函数是什么呢?

async 函数实际上是 Generator 函数的语法糖。

// 懒得写例子了,借用下阮一峰老师的例子const fs = require('fs');
const readFile = function (fileName) { return new Promise(function (resolve, reject) { fs.readFile(fileName, function(error, data) { if (error) return reject(error); resolve(data); }); });};
const gen = function* () { const f1 = yield readFile('/etc/fstab'); const f2 = yield readFile('/etc/shells'); console.log(f1.toString()); console.log(f2.toString());};
// gen函数用async函数改写,如下:const asyncReadFile = async function () { const f1 = await readFile('/etc/fstab'); const f2 = await readFile('/etc/shells'); console.log(f1.toString()); console.log(f2.toString());};
复制代码

可以看出,async函数就是将Generator函数的星号替换成async,将yield替换成await,只不过async函数对Generator函数做了改进。

  1. 内置执行器

Generator函数执行必须靠执行器,调用next方法,或者用co模块;而async函数自带执行器,能像普通函数一样直接执行。

  1. 返回值是Promise

async函数返回值是Promise对象,比而Generator函数返回的是Iterator对象方便多。

  1. 更好的语义

async 和await,比起星号和yield,语义更清楚了。async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果

  1. 更广的适用性

co模块约定,yield命令后面只能是 Thunk 函数或 Promise 对象,而async函数的await命令后面,可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时会自动转成立即 resolvedPromise 对象)。


这里关于Generator函数的学习,可以参考下面文章:

异步编程 Generator()函数


至此我们完成了 async 异步函数的学习。

发布于: 2021 年 01 月 14 日阅读数: 38
用户头像

梁龙先森

关注

脚踏V8引擎的无情写作机器 2018.03.17 加入

还未添加个人简介

评论

发布
暂无评论
重学JS | 异步编程 async/await