Javascript 使用同步代码中的co和承诺(mongoDB示例)

Javascript 使用同步代码中的co和承诺(mongoDB示例),javascript,promise,generator,co,Javascript,Promise,Generator,Co,如何使用co()包装函数与普通同步代码集成 例如,我有co.wrapped这个函数,它使用yield调用mongo上的异步方法: let wrap = co.wrap(function* (collName) { debug("collName", collName); let collection = AppConfig.db.collection(collName); let res = yield collection.findOne({}); debug("res", r

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

例如,我有
co.wrap
ped这个函数,它使用yield调用mongo上的异步方法:

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;
});
这被称为:

//
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主题
TopicsResponse主题+2ms承诺{}
TopicsResponse res+1ms{u id:56d6bdd93cf89d4082e1bd27,
cname:‘nodejs’,
用户名:'bob'}
TopicsResponse topic.then+1ms承诺{未定义}

因此,在
co.wrapped
方法中,res有真实的数据:
{cname:nodejs}
等,但它返回/返回的数据是未定义的

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

我也试过了

yield collection.findOne({});
返回

Promise { undefined }
是否可以通过这种方式使用co使异步代码看起来/运行起来像同步代码?我看到的其他示例只是将所有内容都放在co()的顶层,例如

更新,这项工作使用承诺:

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(
调用)来包装所有东西。当异步函数到达时,它也会以这种方式运行

这不是一个“工件”或设计问题——它实际上非常有用,因为它可以向您显示代码的哪些部分是异步的,哪些部分不是异步的


如果你用
co
包装所有东西,你就有了明确的代码,但不是难看的代码。你确切地知道哪些方法执行I/O,哪些方法不执行I/O。

你的意思是
在生成器函数中返回res
吗?事实上,是的,return res返回了承诺,但它仍然是一个承诺。我想没有办法得到结果(承诺解析?
res
不是承诺-
findOne(…)
是一个承诺。
topic
将是另一个承诺,
doc
结果值。除了将生成器代码包装在
co
中,或者显式使用
然后
之外,没有其他方法获得结果。