Generator
js
function* generateSequence() {
yield 1;
yield 2;
return 3;
}generator function 函数与常规函数不同。
generator function 不会运行代码,而是返回一个被称为 “generator object” 的特殊对象。
generator object 用来管理执行流程。
generator object 的主要方法是 next() ,当 next() 被调用时候,它会恢复 到 最近的 yield。 然后 函数暂停 , 并产出的(yielded)值。
yield 返回的值,为 { value:任意类型 , done:Boolean }
js
const generator = generateSequence();
generator.next();
// { value: 1, done: false }return 3 和 yield 3 一样,只是除此之外 return 还将 done 变为 true、
generator function 可以没有 return。
generator object 是可迭代的
js
function* generateSequence() {
yield 1;
yield 2;
return 3;
}
for (let value of generateSequence()) {
console.log(value);
// 1
// 2
}没有 3,因为 3 的 done 为 true。
“yield” 是一条双向路
js
function* gen() {
let result = yield "2 + 2 = ?";
return result;
}
let generator = gen();
let question = generator.next();
// { value: '2 + 2 = ?', done: false }
generator.next(4);
// { value: 4, done: true }generator.return
主动 return
js
function* gen() {
yield 1;
yield 2;
yield 3;
}
const g = gen();
g.next(); // { value: 1, done: false }
g.return("foo"); // { value: "foo", done: true }
g.next(); // { value: undefined, done: true }
g.return("2333"); // { value: '2333', done: true }generator.throw
主动抛出错误
js
let generator = gen();
generator.throw(new Error());rest
js
[0, ...generateSequence()];composition
generator function 可以进行组合,彼此“嵌入(embed)”到一起
js
function* generateSequence(start, end) {
for (let i = start; i <= end; i++) yield i;
}
function* generatePasswordCodes() {
// 0..9
yield* generateSequence(48, 57);
// A..Z
yield* generateSequence(65, 90);
// a..z
yield* generateSequence(97, 122);
}例子
js
function* range(from, to) {
for (let i = from; i < to; i++) {
yield i;
}
}
for (const i of range(1, 5)) {
console.log(i);
}js
const range = {
*[Symbol.iterator]() {
const from = 1;
const to = 5;
for (let i = from; i <= to; i++) {
yield i;
}
},
};
for (let value of range) {
console.log(value);
}async 异步相关
js
const test = {
[Symbol.iterator]() {
// 正常状况下
},
[Symbol.asyncIterator]() {
// 异步状况下
},
};Symbol.asyncIterator 的 next() ,应该是 promise !!
js
async function* generateSequence(start, end) {
for (let i = start; i <= end; i++) {
// 可以 使用 await !
await new Promise((resolve) => setTimeout(resolve, 1000));
yield i;
}
}js
let generator = generateSequence(1, 5);
for await (let value of generator) {
alert(value); // 1,然后 2,然后 3,然后 4,然后 5(在每个 alert 之间有延迟)
}todos
省略一些内容