0

co() でラップされた関数を使用して、通常の同期コードと統合するにはどうすればよいですか?

たとえば、co.wrapyield を使用して 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()、アプリ全体に振りかける必要はありません...

4

1 に答える 1