使用来自同步代码的co和promises(mongoDB示例)

时间:2016-03-03 17:35:44

标签: javascript promise generator co

如何使用co()包装函数与普通同步代码集成?

例如我有let wrap = co.wrap(function* (collName) { debug("collName", collName); let collection = AppConfig.db.collection(collName); let res = yield collection.findOne({}); debug("res", res); yield res; }); 这个函数使用yield来调用mongo上的异步方法:

//
class TopicsResponse {

  public static topics(bot, message) {
    let topic = wrap("Topics");
    debug("topic", topic);
    topic.then( function() {
      debug("topic.then", topic);
      bot.reply(message, "topics:" + topic.cname);
    });
  }
//
}
用这个来调用


  TopicsResponse collName +3s Topics
  TopicsResponse topic +2ms Promise { <pending> }
  TopicsResponse res +1ms { _id: 56d6bdd93cf89d4082e1bd27,
  cname: 'nodejs',
  username: 'bob' }
  TopicsResponse topic.then +1ms Promise { undefined }

给出如下所示的日志:

co.wrapped

因此在{ cname: nodejs }方法中,res具有实际数据:yield collection.findOne({}); 等。但它返回/返回的内容是未定义的。

我认为这与生成承诺的生成器函数有关。

我也试过

Promise { undefined }

返回

let getTopic = co.wrap(function* (collName) {
  debug("collName", collName);
  let collection = AppConfig.db.collection(collName);
  let res = yield collection.findOne({});
  debug("res", res);  // prints correctly
  return res;
  // yield res;
});



//
class TopicsResponse {

  public static topics(bot, message) {
    let topic = getTopic("Topics");
    debug("topic", topic);
    topic.then( function(doc) {
      debug("doc", doc);
      debug("topic.then", topic);
      bot.reply(message, "topics:" + doc.cname);
    });
  }
//
}

是否有可能以这种方式使用同步代码看起来/运行异步代码?我见过的其他例子只是将co()中的所有内容放在顶层,例如http://mongodb.github.io/node-mongodb-native/2.1/api/Collection.html#find

更新,这可以使用promises:

.then()

但我想将所有包含final= "${output}""${cleanname}".mp4代码的丑陋承诺推送到库中,而不必将其全部洒在我的应用程序上......

1 个答案:

答案 0 :(得分:0)

不,一旦你&#34;脏&#34;承诺它必须一直承诺你的代码(它与回调的方式相同)。

您必须使用co(电话打包所有内容。当这些降落时,这也会以异步函数的方式运行。

这不是&#34;神器&#34;或设计问题 - 它实际上非常有用,因为它可以向您显示代码的哪些部分是异步的,哪些部分不是。

如果你在co中包装所有内容,那么你有明确的代码 - 但不是丑陋的代码。您确切知道哪些方法可以执行以及哪些方法不执行I / O.