如何将 yield 与我自己的函数一起使用?

How to use yield with my own functions?

我是 Generator 概念的新手。我的理解是,如果一个函数returns一个Promise,那么它可以和yield一起使用。所以我有一个非常小的 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 不适用于生成器函数。您需要为此使用 dedicated generator methods,在您的情况下 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 可以包装生成器并使其可调用。它 returns 承诺。

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

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