在 JavaScript 中实现协程控制流 [英] Implementing coroutine control flow in JavaScript
本文介绍了在 JavaScript 中实现协程控制流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
下面实现了一个控制流包装器 co
,使异步代码只能由 yield
关键字描述.
The following implements a control flow wrapper co
enabling asynchronous code to be delineated only by the yield
keyword.
这基本上是 async
/await
在 ESwhatever 中所做的吗?
Is this basically what async
/await
does under the hood in 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));
}
根据我更新的响应以考虑返回值:
In light of the responses I updated to take into consideration return values:
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));
}
推荐答案
这基本上就是 ESwhatever 中的 async/await 所做的事情吗?
Is this basically what async/await does under the hood in ESwhatever?
不是真的.这是一种不同的方法来做同样的事情.async/await
变成的更像是
Not really. It's a different approach for doing sorta the same thing. What async/await
turn into is more like
async function foo() {
const bar = await Bar();
bar++;
const baz = await Baz(bar);
return baz;
}
变成
function foo() {
return Bar()
.then(bar => {
bar++;
return Baz(bar)
.then(baz => {
return baz;
});
});
}
这篇关于在 JavaScript 中实现协程控制流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文