generator 和 iterator
對於 generator 生成的迭代器,調用函數,該函數並不執行,返回的也不是函數運行結果,而是一個指向內部狀態的指針對象,總是需要手動調用 next 函數去獲取下一個迭代器狀態
function* helloWorldGenerator() {
yield 'hello';
yield 'world';
return 'ending';
}
var hw = helloWorldGenerator(); // 返回一個狀態
hw.next()
// { value: 'hello', done: false }
hw.next()
// { value: 'world', done: false }
hw.next()
// { value: 'ending', done: true } done 爲 true 代表狀態機執行完
hw.next()
// { value: undefined, done: true }
上例來自 generator
封裝 generator 爲 自執行函數 async
async 可以看做迭代器的一個語法糖,在async 裏面封裝一個 自執行函數,需要注意 async 函數裏面所有異步都會被同步處理,上一個異步執行完成纔會執行下一個異步操作,最後返回 Promise 對象
封裝 promise 異步操作
function gen(time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(time)
resolve()
}, time)
})
}
function* generator() {
yield gen(100);
yield gen(200);
}
function _async(gen) {
return new Promise((resolve, reject) => {
const iter = gen();
const res = [];
const run = () => {
let item = iter.next();
if (!item.done) {
res.push(item.value);
item.value.then(() => {
run();
});
} else {
resolve(res);
}
};
run();
})
}
_async(generator).then(res => console.log(res));
封裝其他異步操作
通過回調函數形式去調用 next 執行,獲取下一個狀態
function gen(fb, time) {
setTimeout(_ => {
console.log(time)
fb(time)
}, time);
}
function* generator(fb) {
yield gen(fb, 100);
yield gen(fb, 200);
}
function _async(gen) {
return new Promise((resolve, reject) => {
const run = () => {
let item = iter.next(run);
if (!item.done) {
res.push(item.value);
} else {
resolve(res);
}
};
const iter = gen(run);
const res = [];
run();
})
}
_async(generator);