promise的用法示例:

1
2
3
4
5
Promise.resolve(a).then(b => {
// do someting
}).then(c => {
// do someting
})

换为async/await用法示例:

1
2
3
4
5
async () => {
const a = await Promise.resolve(a)
const b = await Promise.resolve(b)
const c = await Promise.resolve(c)
}

换为Generator函数的写法:

1
2
3
4
5
6
7
8
9
10
11
function *myGenerator() {
yield '1';
yield '2';
return '3';
}

const genFn = myGenerator();
genFn.next(); // {value: '1', done: false}
genFn.next(); // {value: '2', done: false}
genFn.next(); // {value: '3', done: true}
genFn.next(); // {value: undefined, done: true}

还可以通过next方法传入参数,让Generator函数的yield语句具有返回值。

1
2
3
4
5
6
7
8
9
10
function *myGenerator() {
console.log(yield '1'); // test1
console.log(yield '2'); // test2
console.log(yield '3'); // test3
}

const genFn = myGenerator();
genFn.next('test1');
genFn.next('test2');
genFn.next('test3');

不同点:

  1. async/await是自动执行,不需要手动调用next()执行下一步骤。
  2. async返回的是Promise对象,Generator函数返回生成器对象。
  3. await能够返回Promise执行resolve/reject的值。

一、自动执行/手动执行

手动执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function *myGenerator() {
yield Promise.resolve('a');
yield Promise.resolve('b');
yield Promise.resolve('c');
}

const gen = myGenerator();

gen.next().value.then(a => {
console.log(a);
gen.next().value.then(b => {
console.log(b);
gen.next().value.then(c => {
console.log(c)
}
})
})
// a
// b
// c

自动执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function run(generator) {
const gen = generator();
function _next(value) {
const result = gen.next();
if(result.done) return result.value;
result.value.then(res => {
_next(res);
})
}
_next();
}

function *generator(){
console.log(yield Promise.resolve('a'));
console.log(yield Promise.resolve('b'));
console.log(yield Promise.resolve('c'));
};
run(generator);
// a
// b
// c

二、返回Promise和捕获异常

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
function run(generator) {
return new Promise((resolve, reject) => {
var gen = generator();
function _next(val) {
try {
var result = gen.next(val);
} catch (error) {
return reject(error);
}
if(result.done) {
return resolve(result.value);
}
Promise.resolve(result.value).then(res => {
_next(res);
}, error => {
gen.throw(error);
})
}
_next();
})
}

// 测试使用
function* myGenerator() {
try {
console.log(yield Promise.resolve(1))
console.log(yield 2) //2
console.log(yield Promise.reject('error'))
} catch (error) {
console.log(error)
}
}

const value = run(myGenerator);
// 1
// 2
// error

Generator

结合上面说的async/await不同点,我们可以知道Generator具有的特点

  1. 调用Generator函数,并不会马上执行它里面的语句,而是返回一个这个生成器的迭代器(iterator)对象。
  2. 可以分段执行,通过调用next()方法,执行下一个步骤。
  3. next()方法固定的返回一个对象,对象里面的value是当前步骤yield后面的值,done可以判断Generator函数是否执行完毕。

一、switch 模拟 缺点需要每次传参

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function gen$(nextStep) {
while(1) {
switch (nextStep) {
case 0:
return 'result1';
case 2:
return 'result2';
case 4:
return 'result3';
case 6:
return undefined;
}
}
}

console.log(gen$(2)); // result2

二、闭包,无需传参,调用一次,执行一次

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
function gen$2() {
var nextStep = 0;
return function (){
while(1) {
switch (nextStep) {
case 0:
nextStep = 2;
return 'result1';
case 2:
nextStep = 4;
return 'result2';
case 4:
nextStep = 6;
return 'result3';
case 6:
return undefined;
}
}
}
}

const fn = gen$2()
fn(); // result1
fn(); // result2
fn(); // result3
fn(); // undefined

三、使用全局变量控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var context = {
next: 0,
prev: 0
}

function gen$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return 'result1';
case 2:
_context.next = 4;
return 'result2';
case 4:
_context.next = 6;
return 'result3';
case 6:
return undefined;
}
}
}

四、next()方法改变执行步骤

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
var context = {
next: 0,
prev: 0
}

function gen$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return 'result1';
case 2:
_context.next = 4;
return 'result2';
case 4:
_context.next = 6;
return 'result3';
case 6:
return undefined;
}
}
}

var gen = function() {
return {
next: function() {
value = gen$(context);
return value;
}
}
}

五、添加状态和改变状态并返回一个对象

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
function gen$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return 'result1';
case 2:
_context.next = 4;
return 'result2';
case 4:
_context.next = 6;
return 'result3';
case 6:
case 'end':
return _context.stop();
}
}
}

var context = {
next: 0,
prev: 0,
done: false,
stop: function stop() {
this.done = true
}
}

let gen = function() {
return {
next: function() {
value = context.done ? undefined : gen$(context)
done = context.done
return {
value,
done
}
}
}
}

var g = gen()
console.log(g.next())
console.log(g.next())
console.log(g.next())
console.log(g.next())

参考:
https://juejin.cn/post/6844904096525189128#heading-14
https://zhuanlan.zhihu.com/p/216060145