async 函数是什么?一句话,它就是 Generator 函数的语法糖。 —es6入门

Generator的用法

  1. function* helloWorldGenerator() {
  2. yield 'hello';
  3. yield 'world';
  4. return 'ending';
  5. }
  6. var hw = helloWorldGenerator();
  7. hw.next() // { value: 'hello', done: false }
  8. hw.next() //{ value: 'world', done: false }
  9. hw.next() //{ value: 'ending', done: true }

Generator和async的比较

  1. const gen = function* () {
  2. const f1 = yield readFile('/etc/fstab');
  3. const f2 = yield readFile('/etc/shells');
  4. console.log(f1.toString());
  5. console.log(f2.toString());
  6. };
  7. const asyncReadFile = async function () {
  8. const f1 = await readFile('/etc/fstab');
  9. const f2 = await readFile('/etc/shells');
  10. console.log(f1.toString());
  11. console.log(f2.toString());
  12. };

两者写法上区别是变成async,yield变成await,
*Generator 函数的执行必须靠执行器,所以才有了co模块,而async函数自带执行器

所以在使用的时候async函数直接调用即可,而generator需要调用并使用next

  1. var test = gen()
  2. test.next() //输出第一个yield

async用法

async的用法比较简单,函数声明成async函数,并在函数中的异步函数前加await,当执行到异步函数时,await会等函数异步操作结果之后再往下执行。

  1. function timeout(ms) {
  2. return new Promise((resolve) => {
  3. setTimeout(resolve, ms);
  4. });
  5. }
  6. async function asyncPrint(value, ms) {
  7. await timeout(ms);
  8. console.log(value);
  9. }
  10. asyncPrint('hello world', 50);

async在循环中的使用

async可以使用在循环中,但是不会改变循环的执行时间,只会改变循环中函数的执行。循环依然会依次快速的执行完,不会等一个循环执行结果在执行第二个循环。
例如:

  1. var a=[3000,1000,2000]
  2. var timePrint = (time)=>{
  3. return new Promise((resolve,reject)=>{
  4. setTimeout(()=>{
  5. console.log(time)
  6. resolve(time)
  7. },time)
  8. })
  9. }
  10. a.forEach(async time=>{
  11. await timePrint(time)
  12. })

image.png
上述代码,for循环中有三个异步操作,第一个3秒返回结果,第二个1秒返回结果,最后一个2秒返回结果,
最后输出的结果是1000、2000、3000. 输出的结果完全是按照时间长短顺序来的。
async并不会影响for循环的执行顺序,也不会影响for循环的执行时间。
for循环执行时,就立即创建了三个异步操作,内部函数的执行是相对独立的异步操作,函数内部的执行顺序是可以受await控制的,如下:
image.png

如何依次执行Promise

如果希望promise依次执行如何操作呢,for循环不行的话,我们可以考虑使用递归循环,在上一个函数结束之后在调用下一个循环,使用await控制运行的顺序

  1. var a=[3000,1000,2000]
  2. var timePrint = (time)=>{
  3. return new Promise((resolve,reject)=>{
  4. setTimeout(()=>{
  5. console.log(time)
  6. resolve(time)
  7. },time)
  8. })
  9. }
  10. var index = 0
  11. var test = async function(){
  12. await timePrint(a[index])
  13. index++
  14. if(index<a.length){
  15. test()
  16. }
  17. }
  18. test()

image.png