【发布时间】:2017-09-18 17:53:18
【问题描述】:
以下实现了一个控制流包装器co,使异步代码只能由yield 关键字描述。
这基本上是 async/await 在 ESwhatever 中所做的吗?
co(function*() {
console.log('...');
yield one();
console.log('...');
yield two();
})
function co(gFn) {
var g = gFn();
return Promise.resolve()
.then(go);
function go() {
var result = g.next();
if(result.done) {
return;
}
if(isPromise(result.value)) {
return result.value.then(go); // Promises block until resolution.
}
return Promise.resolve(result);
}
}
function isPromise(o) {
return o instanceof Promise;
}
function one() {
return new Promise(resolve => setTimeout(() => (console.log('one'), resolve()), 1000));
}
function two() {
return new Promise(resolve => setTimeout(() => (console.log('two'), resolve()), 1000));
}
编辑:
根据我更新以考虑返回值的响应:
co(function*() {
console.log('...');
const result1 = yield one();
console.log('result1: ', result1);
const result2 = yield two();
console.log('result2: ', result2);
const result3 = yield[one(), two()];
console.log('result3: ', result3);
const result4 = yield{
one: one(),
two: two()
};
console.log('result4: ', result4);
})
function co(gFn) {
var g = gFn();
return Promise.resolve().then(go);
function go() {
var result = g.next(...arguments);
if (isPromise(result.value)) {
return result.value.then(go);
}
if (Array.isArray(result.value)) {
return Promise.all(result.value).then(go);
}
if (isObject(result.value)) {
var o = {};
var promises = Object.keys(result.value).map(k=>result.value[k].then(r=>o[k] = r));
return Promise.all(promises).then(()=>o).then(go);
}
return Promise.resolve(result);
}
}
function isPromise(o) {
return o instanceof Promise;
}
function isObject(val) {
return val && (Object === val.constructor);
}
function one() {
return new Promise(resolve=>setTimeout(()=>(console.log('one'),
resolve('result 1')), 1000));
}
function two() {
return new Promise(resolve=>setTimeout(()=>(console.log('two'),
resolve('result 2')), 1000));
}
【问题讨论】:
-
“这基本上是
async/await在 ESwhatever 中所做的事情吗?” 调查仅仅是为了确定一种方法与另一种方法的等效性吗? -
你有没有看过任何转译器的秘密,看看他们是如何实现的?
-
@PhilCooper 我看过
cosource。 -
@guest271314 是的。
-
是的,您已经掌握了基本概念。但是a)你将错误的参数传递给
goFnb)你的go函数没有return result.valuec)你从来没有处理过任何承诺错误(这应该导致g.throw(…))d)await确实不专门处理数组或对象……还有一些更小的东西。
标签: javascript asynchronous async-await generator