Generator是JavaScript中一个比较特殊的函数,它可以被暂停和恢复,并且可以在不阻塞当前线程的情况下,将反复和异步代码转换为同步代码执行。
在ES6之前,JavaScript中没有这样的特殊函数,因此开发人员必须依赖回调和事件循环等工具来处理异步操作。但这种方式很容易导致回调地狱和代码复杂性堆积。而Generator的引入,则有效地解决了这些问题。
在本文中,我们将详细介绍ECMAScript 2021(ES12)中Generator的使用方法,包括定义和执行Generator函数、Generator的特殊语法、yield*表达式、generator.prototype.return()方法等内容。
定义Generator 函数
Generator函数是使用function*
关键字定义的函数。与常规函数不同的是,Generator函数返回一个迭代器对象。
以下是包含简单yield
语句的Generator 函数示例代码:
-- -------------------- ---- ------- --------- ------------------- - ----- -- ----- -- ----- -- - ----- ------------ - -------------------- --------------------------------- --------------------------------- --------------------------------- ---------------------------------
执行结果如下:
{ value: 1, done: false } { value: 2, done: false } { value: 3, done: false } { value: undefined, done: true }
在上面的示例中,可以看到当Generator函数被调用时,它返回了一个Generator对象。该对象拥有一个next()
方法,每次调用该方法时,都会返回一个具有 value
和 done
两个属性的对象。其中value
属性表示 yield
表达式的返回值,而 done
属性则表示Generator
是否已经执行完毕。
Generator特殊语法
ES6之后,Generator函数引入了特殊语法。
其中,最常用且最重要的两个语法分别是yield
和 yield*
表达式。
yield表达式
yield
表达式是Generator函数的核心组成部分。它表示函数执行的暂停和继续。
以下是一个简单的Generator函数示例,其中包含两个yield
表达式:
-- -------------------- ---- ------- --------- ------------- - ---------------------- ----- -- ----------------- - ---- ----- -- - ----- ------------ - -------------- --------------------------------- --------------------------------- ---------------------------------
运行结果如下:
执行到第 1 步 { value: 1, done: false } 执行到第 2 步 { value: 2, done: false } { value: undefined, done: true }
在上面示例中,当一个Generator对象在第一次调用next()
方法时,执行到函数体内的第一个yield
关键字时,函数执行暂停,并将1
作为value
进行返回。再次调用next()
方法时,函数将执行到第二个yield
关键字,并暂停执行。
yield*表达式
yield*
表达式用于将控制权移交到另一个Generator函数中。
以下是一个简单的Generator函数示例,其中通过yield*语句调用了另一个Generator函数:
-- -------------------- ---- ------- --------- --------------------- - ----- - - -- ----- - - -- ----- - - -- - --------- ------------- - ------ ---------------------- ------ ----------------------- - ----- ------------ - -------------- --------------------------------------- --------------------------------------- --------------------------------------- --------------------------------------- --------------------------------------- ---------------------------------------
执行结果如下:
2 3 4 11 12 13
在上面示例中,我们通过yield*
表达式从当前generatorFn()
函数中调用了 anotherGeneratorFn()
函数。因此,Generator
函数执行中的代码直接跳转到了 anotherGeneratorFn()
函数中,直到其所有的值都被返回完毕后再回到原始函数。
运行和关闭Generator对象
Generator对象的运行和终止是重要的考虑因素。如果所有 yield
表达式都被调用,则该生成器进入 done
状态, 表示生成器已退出。
以下是一个简单的Generator函数示例,在其中我们使用了 return()
方法来终止生成器,从而跳过所有剩余的 yield
出现次数:
-- -------------------- ---- ------- --------- --------------- - ----- -- ----- -- ----- -- - ----- ------------ - ---------------- --------------------------------------- --------------------------------------- --------------------------------------------- ---------------------------------------
执行结果如下:
1 2 终止 undefined
在上面的示例中,当调用 generatorObj.return()
方法时,所有剩余的 yield
表达式都会被跳过直至函数退出。此外,返回值 value
属性被设为 return()
方法的参数(即本例中的'终止'
字符串)。
总结
Generator函数是一个非常强大而且实用的特殊函数,可以有效地将反复和异步代码转换为同步代码执行。在ES6之前,JavaScript中没有这样的特殊函数,因此开发人员必须依赖回调和事件循环等工具来处理异步操作。而引入Generator函数,则有效地解决了这些问题。
在本文中,我们详细介绍了ECMAScript 2021(ES12)中Generator的使用方法,包括定义和执行Generator函数、Generator的特殊语法、yield*表达式、generator.prototype.return()方法等内容。如果您长期编写JavaScript代码,那么您肯定需要了解Generator的使用方法,这将帮助您构建更为高效和简洁的代码!
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64ca84d25ad90b6d041b6d30