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是单线程执行,异步操作都是通过事件来处理的。 待续。。。