ECMA6发电机:产量承诺 [英] ECMA6 generators: yield promise

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

问题描述

据我所知,ECMA6发电机应该能够屈服于一个返回承诺的函数,最终返回已解决/拒绝。使代码读取更像同步代码,并避免回调地狱。



我正在使用node.js v0.12.2与 - 和弦和以下代码。 >

  var someAsyncThing = function(){
return new Promise(function(resolve,reject){
resolve(我已经解决了!);
});
};

someAsyncThing()。then(function(res){console.log(res);});
//按预期工作:日志我被解决了!

函数* getPromise(){
var x = yield someAsyncThing();
console.log(x:+ x); // Fails x undefined
}

var y = getPromise();
console.log(y); // return {}

console.log(y.next());
//失败:logs {value:{},done:false}

基于我已经能够在网上找到的几个例子的代码。我做错了什么?

解决方案


据了解,ECMA6发电机应该能够产生一个返回承诺的函数,最终返回解决/拒绝。


不,这不是他们的目的。 ES6生成器应该为编写迭代器提供一种简单的方法 - 每个调用生成器函数都会生成一个迭代器。迭代器只是一个值序列,就像一个数组,但是动态地消耗,并且被懒惰地生成。



现在,生成器可以被滥用控制流程,通过产生一系列异步消耗的承诺,并推进迭代器与每个等待的承诺的结果。请参阅此处,以获得有关未经许可的解释。



那么你的代码丢失是消费者实际上等待承诺并推进您的发电机。通常你会使用专门的图书馆(如 co <​​/a>或 task.js ),或许多承诺库提供的帮助函数之一( Q Bluebird when ,...),但为了这个答案的目的,我将显示一个简化的一个:

  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 生成器:

 运行(getPromise).then(console.log,console.error) ; 


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.

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?

解决方案

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.

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.

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.

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);
    }());
}

Now with this function you can actually "execute" your getPromise generator:

run(getPromise).then(console.log, console.error);

这篇关于ECMA6发电机:产量承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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