co() でラップされた関数を使用して、通常の同期コードと統合するにはどうすればよいですか?
たとえば、co.wrap
yield を使用して mongo で非同期メソッドを呼び出すこの関数を ped にしました。
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 }
。など。ただし、返される/返されるものは未定義です。
これは、promise を生成するジェネレーター関数と関係があると思います。
私も試してみました
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()
、アプリ全体に振りかける必要はありません...