JS for await...of
功能
The for await…of 语句在异步或者同步可迭代对象上(包括 String,Array,Array-like 对象
(比如 arguments 或者 NodeList),TypedArray,Map, Set 和其他对象等等)创建一个迭代循环,
调用自定义迭代钩子,并为每个不同属性的值执行语句。
语法
for await (variable of iterable) {
statement
}
variable
在每次迭代中,将不同属性的值分配给变量。变量有可能以 const, let, 或者 var 来声明。
iterable
被迭代枚举其属性的对象。
迭代异步可迭代对象
你还可以迭代一个明确实现异步迭代协议的对象:
var asyncIterable = {
[Symbol.asyncIterator]() {
return {
i: 0,
next() {
if (this.i < 3) {
return Promise.resolve({ value: this.i++, done: false });
}
return Promise.resolve({ done: true });
}
};
}
};
(async function() {
for await (num of asyncIterable) {
console.log(num);
}
})();
// 0
// 1
// 2
迭代异步生成器
异步生成器已经实现了异步迭代器协议,所以可以用 for await…of 循环。
async function* asyncGenerator() {
var i = 0;
while (i < 3) {
yield i++;
}
}
(async function() {
for await (num of asyncGenerator()) {
console.log(num);
}
})();
// 0
// 1
// 2
有关使用 for await… of 考虑迭代 API 中获取数据的异步 generator 更具体的例子。这个例子首先为一个数据流创建了一个异步 generator,然后使用它来获得这个 API 的响应值的大小。
async function* streamAsyncIterator(stream) {
const reader = stream.getReader();
try {
while (true) {
const { done, value } = await reader.read();
if (done) {
return;
}
yield value;
}
} finally {
reader.releaseLock();
}
}
// 从url获取数据并使用异步 generator 来计算响应值的大小
async function getResponseSize(url) {
const response = await fetch(url);
// Will hold the size of the response, in bytes.
let responseSize = 0;
// 使用for-await-of循环. 异步 generator 会遍历响应值的每一部分
for await (const chunk of streamAsyncIterator(response.body)) {
// Incrementing the total response length.
responseSize += chunk.length;
}
console.log(`Response Size: ${responseSize} bytes`);
// expected output: "Response Size: 1071472"
return responseSize;
}
getResponseSize('https://jsonplaceholder.typicode.com/photos');
规范
Specification | Status | Comment |
---|---|---|
ECMAScript Latest Draft (ECMA-262) ECMAScript Language: The for-in, for-of, and for-await-of Statements |
Draft |