async 函数是什么?一句话,它就是 Generator 函数的语法糖。 —es6入门
Generator的用法
function* helloWorldGenerator() {yield 'hello';yield 'world';return 'ending';}var hw = helloWorldGenerator();hw.next() // { value: 'hello', done: false }hw.next() //{ value: 'world', done: false }hw.next() //{ value: 'ending', done: true }
Generator和async的比较
const gen = function* () {const f1 = yield readFile('/etc/fstab');const f2 = yield readFile('/etc/shells');console.log(f1.toString());console.log(f2.toString());};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,yield变成await,
*Generator 函数的执行必须靠执行器,所以才有了co模块,而async函数自带执行器
所以在使用的时候async函数直接调用即可,而generator需要调用并使用next
var test = gen()test.next() //输出第一个yield
async用法
async的用法比较简单,函数声明成async函数,并在函数中的异步函数前加await,当执行到异步函数时,await会等函数异步操作结果之后再往下执行。
function timeout(ms) {return new Promise((resolve) => {setTimeout(resolve, ms);});}async function asyncPrint(value, ms) {await timeout(ms);console.log(value);}asyncPrint('hello world', 50);
async在循环中的使用
async可以使用在循环中,但是不会改变循环的执行时间,只会改变循环中函数的执行。循环依然会依次快速的执行完,不会等一个循环执行结果在执行第二个循环。
例如:
var a=[3000,1000,2000]var timePrint = (time)=>{return new Promise((resolve,reject)=>{setTimeout(()=>{console.log(time)resolve(time)},time)})}a.forEach(async time=>{await timePrint(time)})

上述代码,for循环中有三个异步操作,第一个3秒返回结果,第二个1秒返回结果,最后一个2秒返回结果,
最后输出的结果是1000、2000、3000. 输出的结果完全是按照时间长短顺序来的。
async并不会影响for循环的执行顺序,也不会影响for循环的执行时间。
for循环执行时,就立即创建了三个异步操作,内部函数的执行是相对独立的异步操作,函数内部的执行顺序是可以受await控制的,如下:
如何依次执行Promise
如果希望promise依次执行如何操作呢,for循环不行的话,我们可以考虑使用递归循环,在上一个函数结束之后在调用下一个循环,使用await控制运行的顺序
var a=[3000,1000,2000]var timePrint = (time)=>{return new Promise((resolve,reject)=>{setTimeout(()=>{console.log(time)resolve(time)},time)})}var index = 0var test = async function(){await timePrint(a[index])index++if(index<a.length){test()}}test()

