摘要:不幸的是,迭代器不能用來表示這樣的數據源。即使是的迭代器也是不夠的,因為它的是異步的,但是迭代器需要同步確定狀態。異步迭代器一個異步迭代器就像一個迭代器,除了它的方法返回一個的。
ES2018 新特性
異步迭代器(本文)
正則表達式反向(lookbehind)斷言
正則表達式 Unicode 轉義
非轉義序列的模板字符串
正則表達式 s/dotAll 模式
正則表達式命名捕獲組
對象展開運算符
Promise.prototype.finally
1. 概述在 ECMAScript 2015(ES6) 中 JavaScript 引入了迭代器接口(iterator)用來遍歷數據。迭代器對象知道如何每次訪問集合中的一項, 并跟蹤該序列中的當前位置。在 JavaScript 中迭代器是一個對象,它提供了一個 next() 方法,用來返回序列中的下一項。這個方法返回包含兩個屬性:done 和 value。
迭代器對象一旦被創建,就可以反復調用 next()。
function makeIterator(array) { let nextIndex = 0; // 初始索引 // 返回一個迭代器對象,對象的屬性是一個 next 方法 return { next: function() { if (nextIndex < array.length) { // 當沒有到達末尾時,返回當前值,并把索引加1 return { value: array[nextIndex++], done: false }; } // 到達末尾,done 屬性為 true return {done: true}; } }; }
一旦初始化,next() 方法可以用來依次訪問對象中的鍵值:
const it = makeIterator(["j", "u", "s", "t"]); it.next().value; // j it.next().value; // u it.next().value; // s it.next().value; // t it.next().value; // undefined it.next().done; // true it.next().value; // undefined2. 可迭代對象
一個定義了迭代行為的對象,比如在 for...of 中循環了哪些值。為了實現可迭代,一個對象必須實現 @@iterator 方法,這意味著這個對象(或其原型鏈中的一個對象)必須具有帶 Symbol.iterator 鍵的屬性:
String,Array,TypedArray,Map 和 Set 都內置可迭代對象,因為它們的原型對象都有一個 Symbol.iterator 方法。
const justjavac = { [Symbol.iterator]: () => { const items = [`j`, `u`, `s`, `t`, `j`, `a`, `v`, `a`, `c`]; return { next: () => ({ done: items.length === 0, value: items.shift() }) } } }
當我們定義了可迭代對象后,就可以在 Array.from、for...of 中使用這個對象:
[...justjavac]; // ["j", "u", "s", "t", "j", "a", "v", "a", "c"] Array.from(justjavac) // ["j", "u", "s", "t", "j", "a", "v", "a", "c"] new Set(justjavac); // {"j", "u", "s", "t", "a", "v", "c"} for (const item of justjavac) { console.log(item) } // j // u // s // t // j // a // v // a // c3. 同步迭代
由于在迭代器方法返回時,序列中的下一個值和數據源的 "done" 狀態必須已知,所以迭代器只適合于表示同步數據源。
雖然 JavaScript 程序員遇到的許多數據源是同步的(比如內存中的列表和其他數據結構),但是其他許多數據源卻不是。例如,任何需要 I/O 訪問的數據源通常都會使用基于事件的或流式異步 API 來表示。不幸的是,迭代器不能用來表示這樣的數據源。
(即使是 promise 的迭代器也是不夠的,因為它的 value 是異步的,但是迭代器需要同步確定 "done" 狀態。)
為了給異步數據源提供通用的數據訪問協議,我們引入了 AsyncIterator 接口,異步迭代語句(for-await-of)和異步生成器函數。
4. 異步迭代器一個異步迭代器就像一個迭代器,除了它的 next() 方法返回一個 { value, done } 的 promise。如上所述,我們必須返回迭代器結果的 promise,因為在迭代器方法返回時,迭代器的下一個值和“完成”狀態可能未知。
我們修改一下之前的代碼:
const justjavac = { - [Symbol.iterator]: () => { + [Symbol.asyncIterator]: () => { const items = [`j`, `u`, `s`, `t`, `j`, `a`, `v`, `a`, `c`]; return { - next: () => ({ + next: () => Promise.resolve({ done: items.length === 0, value: items.shift() }) } } }
好的,我們現在有了一個異步迭代器,代碼如下:
const justjavac = { [Symbol.asyncIterator]: () => { const items = [`j`, `u`, `s`, `t`, `j`, `a`, `v`, `a`, `c`]; return { next: () => Promise.resolve({ done: items.length === 0, value: items.shift() }) } } }
我們可以使用如下代碼進行遍歷:
for await (const item of justjavac) { console.log(item) }
如果你遇到了 SyntaxError: for await (... of ...) is only valid in async functions and async generators 錯誤,那是因為 for-await-of 只能在 async 函數或者 async 生成器里面使用。
修改一下:
(async function(){ for await (const item of justjavac) { console.log(item) } })();5. 同步迭代器 vs 異步迭代器 5.1 Iterators
// 迭代器 interface Iterator { next(value) : IteratorResult; [optional] throw(value) : IteratorResult; [optional] return(value) : IteratorResult; } // 迭代結果 interface IteratorResult { value : any; done : bool; }5.2 Async Iterators
// 異步迭代器 interface AsyncIterator { next(value) : Promise6. 異步生成器函數; [optional] throw(value) : Promise ; [optional] return(value) : Promise ; } // 迭代結果 interface IteratorResult { value : any; done : bool; }
異步生成器函數與生成器函數類似,但有以下區別:
當被調用時,異步生成器函數返回一個對象,"async generator",含有 3 個方法(next,throw,和return),每個方法都返回一個 Promise,Promise 返回 { value, done }。而普通生成器函數并不返回 Promise,而是直接返回 { value, done }。這會自動使返回的異步生成器對象具有異步迭代的功能。
允許使用 await 表達式和 for-await-of 語句。
修改了 yield* 的行為以支持異步迭代。
示例:
async function* readLines(path) { let file = await fileOpen(path); try { while (!file.EOF) { yield await file.readLine(); } } finally { await file.close(); } }
函數返回一個異步生成器(async generator)對象,可以用在 for-await-of 語句中。
7. 實現Chakra - 暫未支持
JavaScriptCore - Safari Tech Preview 40
SpiderMonkey - Firefox 57
V8 - Chrome 63
PolyfillsFacebook 的 Regenerator 項目為 AsyncIterator 接口提供了一個 polyfill,將異步生成器函數變成返回 AsyncIterator 的對象 ECMAScript 5 函數。Regenerator 還不支持 for-await-of 異步迭代語法。
Babylon parser 項目支持異步生成器函數和 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" ] });
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/92934.html
摘要:新特性異步迭代器正則表達式反向斷言正則表達式轉義非轉義序列的模板字符串本文正則表達式模式正則表達式命名捕獲組對象展開運算符這個提案由負責,目前已經進入,本提案是的一部分。因此標準移除了對在帶標簽的模版字符串中轉義序列的語法限制。 ES2018 新特性 異步迭代器 正則表達式反向(lookbehind)斷言 正則表達式 Unicode 轉義 非轉義序列的模板字符串(本文) 正則表達式...
摘要:或者使用來匹配空白字符增加標志在最新的規范中,為的正則表達式增加了一個新的標志用來表示。標志用于指定多行輸入字符串應該被視為多個行。標志只影響和標志只影響目前在正則表示中所有修飾符的含義實現 ES2018 新特性 異步迭代器 正則表達式反向(lookbehind)斷言 正則表達式 Unicode 轉義 非轉義序列的模板字符串 正則表達式 s/dotAll 模式(本文) 正則表達式命...
摘要:為了使程序員能夠一次一個地處理集合中的元素,引入了迭代器接口。迭代器使用該方法獲取對象屬性名稱的數組,然后將其分配給常量。迭代器的缺點是它們不適合表示異步數據源。每次循環時,都會調用迭代器的方法,它返回一個。 前言 原文地址:https://css-tricks.com/new-es2018-features-every-javascript-developer-should-kno...
閱讀 2612·2021-11-16 11:40
閱讀 3409·2021-11-08 13:26
閱讀 871·2021-10-28 09:32
閱讀 3530·2021-09-13 10:26
閱讀 803·2019-08-30 15:55
閱讀 777·2019-08-30 15:44
閱讀 1908·2019-08-30 15:44
閱讀 1756·2019-08-30 13:48