Javascript 如何在我自己的函数中使用yield?

Javascript 如何在我自己的函数中使用yield?,javascript,node.js,generator,q,Javascript,Node.js,Generator,Q,我不熟悉生成器概念。我的理解是,如果函数返回一个承诺,那么它可以与收益一起使用。因此,我有一个非常小的node.js脚本,如下所示: Q.fcall(function*(){ var url = "mongodb://" + config.host + ":" + config.port + "/" + config.db; var db = yield MongoClient.connect( url ); var data = yield makeRequest(); con

我不熟悉
生成器
概念。我的理解是,如果函数返回一个
承诺
,那么它可以与
收益
一起使用。因此,我有一个非常小的node.js脚本,如下所示:

Q.fcall(function*(){
  var url = "mongodb://" + config.host + ":" + config.port + "/" + config.db;
  var db = yield MongoClient.connect( url );
  var data = yield makeRequest();
  console.log( data );
  db.close();
});


function makeRequest(){
  var deferred = Q.defer();
  request({
      "method" : "GET",
      "url" : "....",
      "headers" : {
          "Accept" : "application/json",
          "user_key" : "...."
      }
  },function(err,data){
      if( err ){
          deferred.reject( err );
      }else{
          deferred.resolve( data );
      }
  });
  return deferred.promise;
}  
我知道这是可行的,因为我正在将它从回调地狱风格移植到生成器风格。但是,我在console.log中看不到数据


我需要更改什么才能使其正常工作?

Q.fcall
不适合与发电机功能一起工作。对于这种情况,您需要使用
Q.spawn

Q.spawn(function*() {
  var url = "mongodb://" + config.host + ":" + config.port + "/" + config.db;
  var db = yield MongoClient.connect( url );
  try {
    var data = yield makeRequest();
    console.log( data );
  } finally {
    db.close();
  }
});

如果没有转轮,生成器将无法自动异步推进。

Q.fcall
不适合使用生成器功能。对于这种情况,您需要使用
Q.spawn

Q.spawn(function*() {
  var url = "mongodb://" + config.host + ":" + config.port + "/" + config.db;
  var db = yield MongoClient.connect( url );
  try {
    var data = yield makeRequest();
    console.log( data );
  } finally {
    db.close();
  }
});

如果没有运行程序,生成器将不会自动异步升级。

请考虑使用
co
包装生成器并使其可调用。它回报了承诺

const co = require('co');
const promisedGenerator = co.wrap(function* () {
  yield whatever1();
  yield whatever2();
  return databaseRequest(); 
});

promisedGenerator()
  .then(databaseResult => {
    console.log(databaseResult);
  });

考虑使用
co
,它可以包装生成器并使其可调用。它回报了承诺

const co = require('co');
const promisedGenerator = co.wrap(function* () {
  yield whatever1();
  yield whatever2();
  return databaseRequest(); 
});

promisedGenerator()
  .then(databaseResult => {
    console.log(databaseResult);
  });

“我的理解是,如果函数返回承诺,那么它可以与
yield
一起使用。”生成器(和
yield
)与承诺无关。它们可以一起用于实现类似
async/await
,但是
yield
本身对承诺的处理与任何其他值都没有区别。这应该回答您的问题:@FelixKling谢谢!你发帖子的时候我正在读这篇文章:)@FelixKling我做了一些调查,把
Q.fcall()
改成
co()
,结果成功了。那么,
co
到底做什么呢?:)@据我所知,LittleChild基本上一直在调用
PassedGenerator.next()
,直到返回
{done:true}
对象或出现错误。“我的理解是,如果函数返回承诺,那么它可以与
yield
生成器一起使用(和
yield
)与承诺无关。它们可以一起用于实现类似
async/await
,但是
yield
本身对承诺的处理与任何其他值都没有区别。这应该回答您的问题:@FelixKling谢谢!你发帖子的时候我正在读这篇文章:)@FelixKling我做了一些调查,把
Q.fcall()
改成
co()
,结果成功了。那么,
co
到底做什么呢?:)@据我所知,LittleChild基本上一直在调用
passedGenerator.next()
,直到返回
{done:true}
对象或发生错误。