小言_互联网的博客

generator的返回值和next的参数

341人阅读  评论(0)

看了一篇关于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
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场