yield与yield*区别
JS生成器函数认识不足,最近开发中碰了壁,于是梳理学习,Mark下。
yield vs yield*
yield
The yield keyword is used to pause and resume a generator function or legacy generator function.
yield 关键字用来暂停和恢复一个生成器函数((function* 或遗留的生成器函数)。
yield*
The yield* expression is used to delegate to another generator or iterable object.
yield* 表达式用于委托给另一个generator 或可迭代对象。
举个例子
 function* sub() {
        for (let i = 65; i < 70; i++) {
          yield String.fromCharCode(i);
        }
      }
      function* main() {
        yield 'begin';
        yield sub();
        yield '---------';
        yield* sub();
        yield 'end';
        return 'main end';
      }
      for (const i of main()) {
        console.log(i);
      }

控制台打印可以看出
- yield与yield*不同
- yield返回的sub迭代器,而yield*是sub迭代器中的每个yield元素
我是这么理解*是通配,即所有,yield*将表达式中的每个项都委托了出去,而yield是整体委托。
另外,注意到上述main生成器函数是有返回值,但却没有打印,这是为什么呢?这是因为forof遍历无法获取返回值,假如改造下,即可正常获取。
const res = main();
      let value = null;
      while (value !== undefined) {
        value = res.next().value;
        if (value !== undefined) {
          console.log(value);
        }
      }

Redux-Saga中使用场景
- 当前,在实际开发中,与生成器打交道最多的地方是Redux-Saga写effects时就要用到,从效果来说yield还是yield*效果一致 
- 官网对于yield,yield*的使用diff说明很粗糙,只是告诉你不一样。。。。 - You can use the builtin - yield*operator to compose multiple Sagas in a sequential way. This allows you to sequence your macro-tasks in a procedural style.- 你可以使用内置的 - yield*操作符来组合多个 Sagas,使得它们保持顺序。 这让你可以一种简单的程序风格来排列你的 宏观任务(macro-tasks)。
个人理解
- saga中我们编排的这些副作用处理大多是异步【宏任务】,异步即有顺序存在- 如果我们需要确保A effects所有的异步【包括A调用B effects,B中的异步】都按照既定的顺序进行执行,那么就要使用yield*,如果A effects中只有一个B effects,那么yield,还是yield* 结果均相同
 
举个例子
与Promise
promise的出现是为了解决异步编程-callback方案带来的回调地狱。


