ECMA6 生成器:收益承诺 [英] ECMA6 generators: yield promise
问题描述
据我所知,ECMA6 生成器应该能够屈服于返回承诺的函数,最终返回已解决/已拒绝的.让代码读起来更像同步代码,避免回调地狱.
As I understand it ECMA6 generators are supposed to be able to yield to a function that returns a promise, eventually returning the resolved/rejected. Making the code read more like synchronous code, and avoiding callback hell.
我正在使用带有 --harmony 和以下代码的 node.js v0.12.2.
I am using node.js v0.12.2 with --harmony and the following code.
var someAsyncThing = function() {
return new Promise(function(resolve, reject) {
resolve("I'm Resolved!");
});
};
someAsyncThing().then(function(res) {console.log(res);});
// Works as expected: logs I'm Resolved!
function* getPromise() {
var x = yield someAsyncThing();
console.log("x: " + x); // Fails x undefined
}
var y = getPromise();
console.log(y); // returns {}
console.log(y.next());
// Fails: logs { value: {}, done: false }
我根据我在网上能找到的几个例子编写了代码.我做错了什么?
I've based the code off of the few examples I have been able to find online. What am I doing wrong?
推荐答案
据我所知,ECMA6 生成器应该能够屈服于返回承诺的函数,最终返回已解决/已拒绝的.
As I understand it ECMA6 generators are supposed to be able to yield to a function that returns a promise, eventually returning the resolved/rejected.
不,这不是他们的目的.ES6 生成器应该提供一种简单的方法来编写迭代器——对生成器函数的每次调用都会产生一个迭代器.迭代器只是一个值序列——就像一个数组,但动态消耗和延迟生成.
No, that's not their purpose. ES6 generators are supposed to provide a simple way for writing iterators - each call to a generator function produces an iterator. An iterator is just a sequence of values - like an array, but consumed dynamically and produced lazily.
现在,生成器可以被滥用用于异步控制流,方法是生成一系列异步使用的 Promise 并用每个等待的 Promise 的结果推进迭代器.请参阅此处,了解无承诺的解释.
Now, generators can be abused for asynchronous control flow, by producing a sequence of promises that is consumed asynchronously and advancing the iterator with the results of each awaited promise. See here for an explanation without promises.
所以你的代码缺少的是实际等待承诺并推进你的生成器的消费者.通常你会使用一个专用的库(比如 co 或 task.js),或许多 Promise 库提供的辅助函数之一(Q, 蓝鸟、when、……),但为了这个答案的目的,我将展示一个简化的:
So what your code is missing is the consumer that actually waits for the promises and advances your generator. Usually you'd use a dedicated library (like co or task.js), or one of the helper functions that many promise libraries provide (Q, Bluebird, when, …), but for the purposes of this answer I'll show a simplified one:
function run(gf) {
let g = gf();
return Promise.resolve(function step(v) {
var res = g.next(v);
if (res.done) return res.value;
return res.value.then(step);
}());
}
现在有了这个函数,你实际上可以执行"你的 getPromise
生成器:
Now with this function you can actually "execute" your getPromise
generator:
run(getPromise).then(console.log, console.error);
这篇关于ECMA6 生成器:收益承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!