Javascript 使用同步代码中的co和承诺(mongoDB示例)
如何使用co()包装函数与普通同步代码集成 例如,我有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.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
中,或者显式使用然后之外,没有其他方法获得结果。