当前位置: 首页 > 后端技术 > Node.js

ES2018新特性:异步迭代器for-await-of

时间:2023-04-03 15:46:38 Node.js

ES2018新特性异步迭代器(本文)正则表达式反向(lookbehind)assert正则表达式Unicode转义序列模板字符串正则表达式公式s/dotAll模式正则表达式命名捕获组对象扩展运算符Promise.prototype.finally1。概述在ECMAScript2015(ES6)中,JavaScript引入了迭代器接口(iterator)来遍历数据。迭代器对象知道如何一次访问集合中的一项并跟踪其在序列中的当前位置。JavaScript中的迭代器是一个提供next()方法的对象,该方法返回序列中的下一项。此方法返回两个属性:done和value。一旦创建了迭代器对象,就可以重复调用next()。函数makeIterator(array){让nextIndex=0;//initialindex//返回一个迭代器对象,其属性是一个next方法return{next:function(){if(nextIndex{constitems=[`j`,`u`,`s`,`t`,`j`,`a`,`v`,`a`,`c`];return{next:()=>({done:items.length===0,value:items.shift()})}}}当我们定义一个可迭代对象时,我们可以在Array.from中使用这个对象,对于...of:[...justjavac];//["j","u","s","t","j","a","v","a","c"]Array.from(justjavac)//["j","u","s","t","j","a","v","a","c"]newSet(justjavac);//{"j","u","s","t","a","v","c"}for(constitemofjustjavac){console.log(item)}//j//u//s//t//j//a//v//a//c3。同步迭代由于迭代器方法的返回,下一个值和数据源的“完成”状态必须是已知的,所以迭代器只适用于表示同步数据源。虽然JavaScript程序员遇到的许多数据源是同步的(例如内存列表和其他数据结构),但许多其他数据源不是。例如,任何需要I/O访问的数据源通常会使用基于事件或流式异步API来表示。遗憾的是,迭代器不能用于表示此类数据源。(即使是promise迭代器也是不够的,因为它的值是异步的,但是迭代器需要同步判断“done”状态。)为了给异步数据源提供一个通用的数据访问协议,我们引入了AsyncIterator接口,异步迭代语句(for-await-of)和异步生成器函数。4.异步迭代器异步迭代器就像一个迭代器,除了它的next()方法返回{value,done}的承诺。如上所述,我们必须返回迭代器结果的承诺,因为在迭代器方法返回时可能不知道迭代器的下一个值和“完成”状态。让我们修改之前的代码:constjustjavac={-[Symbol.iterator]:()=>{+[Symbol.asyncIterator]:()=>{constitems=[`j`,`u`,`s`,`t`,`j`,`a`,`v`,`a`,`c`];return{-next:()=>({+next:()=>Promise.resolve({done:items.length===0,value:items.shift()})}}}好的,我们现在有一个异步迭代器,代码如下:constjustjavac={[Symbol.asyncIterator]:()=>{constitems=[`j`,`u`,`s`,`t`,`j`,`a`,`v`,`a`,`c`];return{next:()=>Promise.resolve({done:items.length===0,value:items.shift()})}}}我们可以用下面的代码来遍历:generators错误,这是因为for-await-of只能在异步函数或异步生成器中使用。修改它:(asyncfunction(){forawait(constitemofjustjavac){console.log(item)}})();5.同步迭代器vs异步迭代器5.1迭代器//IteratorinterfaceIterator{next(value):IteratorResult;[可选]throw(value):IteratorResult;[optional]return(value):IteratorResult;}//迭代结果接口IteratorResult{value:any;done:bool;}5.2AsyncIterators//异步迭代器接口AsyncIterator{next(value):Promise;[可选]throw(value):Promise;[optional]return(value):Promise;}//迭代结果接口IteratorResult{value:any;done:bool;}6.异步生成器函数异步生成器函数类似于生成器函数,但有以下区别:异步生成器函数在调用时返回一个对象“asyncgenerator”,它有3个方法(next、throw和return),每个方法返回一个Promise,Promise返回{value,done}。普通的generator函数不会返回Promise,而是直接返回{value,done}。这会自动使返回的异步生成器对象能够进行异步迭代。允许使用等待表达式和for-await-of语句。修改了yield*的行为以支持异步迭代。示例:asyncfunction*readLines(path){letfile=awaitfileOpen(path);try{while(!file.EOF){yieldawaitfile.readLine();}}最后{awaitfile.close();}}该函数返回一个异步生成器对象,可以在for-await-of语句中使用。7.实施Chakra-JavaScriptCore尚不支持-SafariTechPreview40SpiderMonkey-Firefox57V8-Chrome63PolyfillsFacebook的Regenerator项目为AsyncIterator接口提供了一个polyfill,将异步生成器函数转换为返回AsyncIterator对象的ECMAScript5函数。Regenerator尚不支持for-await-of异步迭代语法。Babylon解析器项目支持异步生成器函数和for-await-of语句(v6.8.0+)。您可以使用其asyncGenerators插件。require("babylon").parse("code",{sourceType:"module",plugins:["asyncGenerators"]});此外,从6.16.0开始,异步迭代包含在Babel的“babel-plugin-transform-async-generator-functions”和babel-preset-stage-3中。require("babel-core").transform("code",{plugins:["transform-async-generator-functions"]});