如何使用 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 Topics
TopicsResponse topic +2ms Promise { <pending> }
TopicsResponse res +1ms { _id: 56d6bdd93cf89d4082e1bd27,
cname: 'nodejs',
username: 'bob' }
TopicsResponse topic.then +1ms Promise { undefined }
所以在co.wrapped
方法内部, res 有真实的数据:{ cname: nodejs }
等等。但它返回/返回的内容是未定义的。
我认为这与生成器函数产生一个承诺有关..
我也试过了
yield collection.findOne({});
返回
Promise { undefined }
是否有可能以这种方式使用 co 来使异步代码看起来/运行像同步代码?我见过的其他示例只是将所有内容都放在顶层 co() 中,例如http://mongodb.github.io/node-mongodb-native/2.1/api/Collection.html#find
更新,这使用承诺:
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);
});
}
//
}
但我想将所有丑陋的承诺包装.then()
代码推入库中,而不必将它撒在我的应用程序中......