【发布时间】:2016-03-03 17:35:43
【问题描述】:
如何使用 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", 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
更新,这使用 Promise 有效:
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() 代码的丑陋承诺推送到库中,而不必将其洒在我的应用程序中...
【问题讨论】:
-
您的意思是生成器函数中的
return res吗? -
其实是的,return res 还给了promise,但它仍然是一个promise。我想没有办法得到结果(承诺解决方案?)
-
res不是一个承诺 -findOne(…)是一个。topic将是另一个承诺,doc是结果值。除了将生成器代码包装在co中或明确使用then之外,没有其他方法可以得到结果。
标签: javascript promise generator co