1. 了解迭代器:用生成器生成ID序列
function* IdGenerator() {
let id = 0;
while (true) {
yield ++id;
}
}
const idIterator = IdGenerator();
const obj1 = { id: idIterator.next().value };
const obj2 = { id: idIterator.next().value };
const obj3 = { id: idIterator.next().value };
console.log(obj1.id);
console.log(obj2.id);
2. 把执行权交给下一个生成器
function* outerGenerator() {
yield '1';
yield* innerGenerator();
yield '2';
}
function* innerGenerator() {
yield 'a';
yield 'b';
}
for (let res of outerGenerator()) {
console.log(res);// 1 a b 2
}
3. 用迭代器遍历DOM树
function* DomTraversal(element) {
yield element;
element = element.firstElementChild;
while (element) {
// 用yield*将迭代控制转移到另一个DomTraversal生成器实例上
yield* DomTraversal(element);
element = element.nextElementSibling;
}
}
const subTree = document.getElementById('subTree');
for (let element of DomTraversal(subTree)) {
console.log(element);
}
4. 与生成器交互
function* Generator(guest) {
const host = yield 'Hello ' + guest;
yield 'I am ' + host;
}
const it = Generator('aaa');
console.log(it.next().value);// Hello aaa
//参数会赋值给host
console.log(it.next('yf').value);// I am yf
5. 将promise和生成器结合
有些异步任务长期运行且相互依赖,为了不阻塞UI,可以结合生成器+Promise来解决:
把异步任务放入一个生成器中,然后执行生成器函数。在该生成器执行的过程中,每执行到一个异步函数,就创建一个promise用于代表该异步函数的执行结果。我们没办法知道承诺什么时候会兑现(甚至会不会兑现),所以在生成器执行的时候,我们将执行权让渡给生成器,从而不会导致阻塞。
function async(generator) {
let it = generator();
try {
handle(it.next());
} catch (e) {
it.throw(e);
}
function handle(itResult) {
if (itResult.done) return;
const itValue = itResult.value;
if (itValue instanceof Promise) {
itValue.then(res => handle(it.next(res))).catch(err => it.throw(err));
}
}
}
async(function* () {
try {
const item1 = yield getJSON('./aaa.json');
const item2 = yield getJSON(item1.url);
const item3 = yield getJSON(item2.url);
} catch (e) {
throw new Error(e);
}
});
6. async/await
async和await可以更优雅的实现5中的功能
(async function () {
try {
const item1 = await getJSON('./aaa.json');
const item2 = await getJSON(item1.url);
const item3 = await getJSON(item2.url);
} catch (e) {
throw new Error(e);
}
})()