redux-saga中大量涉及到Es6的generator語法,於是乎將generator/promise/async之間的關聯和區別複習一下。這些語法糖的出現無外乎是為了簡化深度回撥,寫法的簡化,程式碼的方便閱讀。
generator
generator迭代器語法中涉及的語法糖*和yield。 *用在生成器函式的開頭。
// a simple generator function
function* gen() {
yield 1;
yield 2;
yield *[3,4,5];
}
var res = gen();
res.next(); // {value: 1, done: false}
for(var value of gen()) {
console.log(value);
}
// result is 1,2,3,4,5
複製程式碼
generator的yield語法返回一個物件{value: val, done: false/true},generator函式相對於迭代器,next指向下一個yield。generator的yield後面可以放同步和非同步操作。
await/async
Promise是鏈式的then來完成每個task。而await/async的出現使得非同步的操作在寫法上和同步一樣,並且每個await時間只能處理一個非同步操作。
async function init() {
await doTask1();
await doTask2();
await doTask3();
}
// an implementation using a generator function
function* init() {
yield doTask1();
yield doTask2();
yield doTask3();
}
// execute generator function
function runner(genFn) {
const itr = genFn();
function run(arg) {
const result = itr.next(arg);
if (result.done) {
return result.value;
} else {
return Promise.resolve(result.value).then(run);
}
}
return run();
}
複製程式碼
async/await可以使用Promise加generator來實現。
async function foo() {
await bar();
}
// babel 的編譯結果
// https://hackernoon.com/async-await-generators-promises-51f1a6ceede2
let foo = (() => {
var _ref = _asyncToGenerator(function* () {
yield doTask1();
});
return function foo() {
return _ref.apply(this, arguments);
}
})();
function _asyncToGenerator(fn) {
return () => {
var gen = fn.apply(this, arguments);
return new Promise((resolve, reject) =>{
function step(key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch(error) {
reject(error);
return;
}
if (info.done) {
resolve(value);
} else {
return Promise.resolve(value).then((value => {
step("next", value);
}, (err) => {
step("throw", err);
}));
}
}
return step("next");
})
}
}
複製程式碼
Promise Vs Async
Promise:
function handler() {
return validateParams()
.then(dbQuery)
.then(serviceCall)
.then(result => {
return result;
})
}
複製程式碼
async 函式
async function handler() {
await validateParams();
const dbResults = await dbQuery();
const results = await serviceCall(dbResults);
return results;
}
複製程式碼
Event loop
Javascript是單執行緒執行,非同步操作都是通過事件來處理的。 待續。。。