5

私はノードが少し初めてで、koa はまったく初めてです。ジェネレーターを使用して API への非同期 Web 要求を実行しようとしていますが、すべての要素をまとめる方法がわかりません。

注意として、いくつかの例がそれを行うのを見たので、私はブルーバードを使用しています。それは良い考えのように思えました。ブルーバードなしでやりたいことをもっと簡単に行う方法があれば、それもまったく問題ありません。

私のモジュールでは:

plugin.searchForItem = function * (name) {
  Promise = require('bluebird');
  request = Promise.promisifyAll(require('request'));
  console.log("making request");
  yield request.getAsync('http://apisitegoeshere.com/apicall').then(function * (result) {
    var response = result[0];
    var body = result[1];
    console.log(response.statusCode);
    yield response;
  });
};

そして、私はそれを次のように呼んでいます:

search.searchForShow = function (name) {
  data = this.plugins[0].searchForItem(name);
  console.log("search returned: " + data);
  console.log("search returned2: " + JSON.stringify(data.next()));
  console.log("search returned3: " + JSON.stringify(data.next()));
  return data;
};

コンソールを見ると、次のように表示されます。

search returned: [object Generator]
making request
search returned2: {"value":{"isFulfilled":false,"isRejected":false},"done":false}
search returned3: {"done":true}

私のコードがいたるところにあることは知っていますが、何時間も作業してきましたが、まだ修正に近づいていません。

ありがとう!

4

3 に答える 3

4

実行時コードを呼び出さないpromisifyAllでください。これは不要であり、アプリケーション ロジックを混乱させ、そこに属さず、非常に低速です。

メソッドをコルーチンとしてマークする必要があります。そうしないと、単なるジェネレーターになります。

var Promise = require("bluebird");
// Assumes request is promisified else where, like in your init file
var request = require("request");

plugin.searchForItem = Promise.coroutine(function* (name) {
    var response = yield request.getAsync("http://www.google.com").get(0);
    console.log(response.statusCode);
    return response;
});

コルーチンは、別のコルーチンで使用したり、Promise として使用したりできる Promise を返します。すでにジェネレーターを使用しているため、別のコルーチンを使用することもできます。

search.searchForShow = Promise.coroutine(function* (name) {
  var data = yield this.plugins[0].searchForItem(name);
  console.log("search returned: " + data);
  return data;
});
于 2014-12-23T17:01:00.083 に答える
1

からジェネレーターを呼び出すこと.thenは、ほとんど機能しません。ジェネレーターを呼び出すと、イテレーターが返されるだけで、何もしません。あなたが望むのは(未テスト)のようなものです:

plugin.searchForItem = function * (name) {
  Promise = require('bluebird');
  request = Promise.promisifyAll(require('request'));
  console.log("making request");
  var result = yield request.getAsync('http://apisitegoeshere.com/apicall');
  var response = result[0];
  var body = result[1];
  console.log(response.statusCode);
  yield response;
};

する必要はありません.then。それがコアの仕事です。それはあなたが得たプロミスを取得し、それが解決するのを待ち、解決された値をパラメーターとして に返しますiterator.next()。これが variableresultになり、関数は次yield(または関数の最後) に進みます。

ただし、あなたの場合、最後の行で行っているように、応答を生成する必要があるかどうかは明確ではありません。1 つには、約束を守らなければならないため、おそらく Koa の実行時エラーが発生します。私はあなたがちょうどのようなものが欲しいと思う

this.body = response;
于 2014-12-23T16:29:55.303 に答える
0

co-request buildなどの既存のリクエストラッパーを使用して、 koaが構築されているcoライブラリを操作することを検討してください。

コアでは、次のようにします。

// server.js
var request = require('co-request');

app.use(function *(){
    try{
        var result = yield request('http://apisitegoeshere.com/apicall');       
        this.body = result.body;
    }
    catch(err){
        this.throw(500);
    }

});
于 2014-12-23T23:11:14.407 に答える