# 10. async,await原理代码实现

function fn(n) {
  return new Promise((resolve,reject)=>{
    setTimeout(() => {
      resolve(n);
    }, 2000);
  })
}
// async function test() {
//   let a = await fn('a');
//   console.log(a);
//   let b = await fn('b');
//   console.log(b);
//   let c = await fn('c');
//   console.log(c);
//   return [a,b,c];
// }
// test().then(v=>{
//   console.log('success',v);
// },e=>{
//   console.log('trow',e);
// })

/* async/await是Generator生成器的语法糖 */
/* 将async/await写法改为Generator/Promise写法 */
function test() {
  let _test = asyncToGenerator(function* () {
    let a = yield fn('a');
    console.log(a);
    let b = yield fn('b');
    console.log(b);
    let c = yield fn('c');
    console.log(c);
    return [a,b,c];
  });
  return _test.apply(this,arguments);
}

function asyncToGenerator(fn) {
  return function() {
    let gen = fn.apply(this,arguments);//遍历器对象
    return new Promise((resolve,reject)=>{
      function step(key,args) {
        let res;
        try {
          res = gen[key](args);//next传入的参数是上一个yield的返回值。
        } catch (error) {
          reject(error);
        }
        let {done,value} = res;
        if (done) {
          resolve(value);
        } else {
          return Promise.resolve(value).then(v=>step('next',v),e=>step('throw',e));
        }
      }
      step('next');
    })
  }
}

test().then(v=>{
  console.log('success',v);
},e=>{
  console.log('trow',e);
})

// a
// b
// c
// success [ 'a', 'b', 'c' ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70