看了一篇关于generator和async/await关系的文章,受益匪浅。
文章的主要内容是:await是generator的语法糖
// Generator
run(function*() {
const res1 = yield readFile(path.resolve(__dirname, '../data/a.json'), { encoding: 'utf8' });
console.log(res1);
const res2 = yield readFile(path.resolve(__dirname, '../data/b.json'), { encoding: 'utf8' });
console.log(res2);
});
// async/await
const readFile = async ()=>{
const res1 = await readFile(path.resolve(__dirname, '../data/a.json'), { encoding: 'utf8' });
console.log(res1);
const res2 = await readFile(path.resolve(__dirname, '../data/b.json'), { encoding: 'utf8' });
console.log(res2);
return 'done';
}
const res = readFile();
可以看到,async function 代替了 function*,await 代替了 yield,同时也无需自己手写一个自动执行器 run 了
但是对于文章内代码的一些细节有一些疑惑,因此写下自己的一些猜想,待日后考证
function* another() {
yield '人月神话';
}
function* gen() {
yield* another(); // 移交执行权
const a = yield 'hello';
const b = yield a; // a='world' 是 next('world') 传参赋值给了上一个 yidle 'hello' 的左值
yield b; // b=! 是 next('!') 传参赋值给了上一个 yidle a 的左值
}
const g = gen();
g.next(); // {value: "人月神话", done: false}
g.next(); // {value: "hello", done: false}
g.next('world'); // {value: "world", done: false} 将 'world' 赋给上一条 yield 'hello' 的左值,即执行 a='world',
g.next('!'); // {value: "!", done: false} 将 '!' 赋给上一条 yield a 的左值,即执行 b='!',返回 b
g.next(); // {value: undefined, done: false}
猜想:
第一次g.next()
,执行完yield* another()
第二次g.next()
, 执行完yield 'hello'
,并将hello
作为g.next()
的返回值。但没有执行const a 的赋值
第三次g.next('world')
,将world赋值给上一条的a,并执行完yield a
,即yield world
,将world返回。此时const b还没有赋值。
第四次g.next('!')
,将!赋值给上一条的b,并执行完yield b
,将!返回
证明:
const promisify = require('util').promisify;
const path = require('path');
const fs = require('fs');
const readFile = promisify(fs.readFile);
const gen = function*() {
const res1 = yield readFile(path.resolve(__dirname, '../data/a.json'), { encoding: 'utf8' });
console.log(res1);
const res2 = yield readFile(path.resolve(__dirname, '../data/b.json'), { encoding: 'utf8' });
console.log(res2);
};
const g = gen();
const g1 = g.next(); // 获取第一个yield的返回值,此时函数内const res1未赋值
console.log('g1:', g1);
g1.value
.then(res1 => { // value的值传给res1,此处是promise
console.log('res1:', res1);
const g2 = g.next(res1); // res1的值传给函数内的const res1,并执行完第二个yield,返回结果给g2。中间又输出了一次res1,
console.log('g2:', g2);
g2.value
.then(res2 => {
console.log('res2:', res2); //同上
g.next(res2);
})
.catch(err2 => {
console.log(err2);
});
})
.catch(err1 => {
console.log(err1);
});
// g1: { value: Promise { <pending> }, done: false }
// res1: {
// "a": 1
// }
// {
// "a": 1
// }
// g2: { value: Promise { <pending> }, done: false }
// res2: {
// "b": 2
// }
// {
// "b": 2
// }
转载:https://blog.csdn.net/huangbx_tx/article/details/102485269
查看评论