ECMA6 生成器:收益承诺 [英] ECMA6 generators: yield promise

查看:16
本文介绍了ECMA6 生成器:收益承诺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,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.

所以你的代码缺少的是实际等待承诺并推进你的生成器的消费者.通常你会使用一个专用的库(比如 cotask.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆