1

これが正しい方法かどうかはわかりませんが、for ループで 10 個の API リクエストを作成しようとしており、すべての API リクエストをブロックしたいと考えています。つまり、コールバックに移動せずに応答を受信するまで待機してから、再び for ループを反復します。ここに for ループがあります

for (var i=0; i< out.items.length; i++) {
    var object = makediffbotAPIcall(out.items[i]);
    console.log(object);
}

リクエスト関数は次のとおりです

function makediffbotAPIcall(item, array) {
    var url_to_send_diffbot = "string of url here";

    request(url_to_send_diffbot, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            var article_object = JSON.parse(body)       
            var object = {"Title": article_object.title, "Url":article_object.url};
        }

    });

    return object;
}

このコードの問題は、オブジェクトが foor ループで使用されるのに間に合わないことです。makediffbotAPIcall 関数の最後に setTimeout を入れてみましたが、それもうまくいきませんでした。どんな提案でも大歓迎です。ありがとう!

4

4 に答える 4

4

非同期環境で制御フローを管理するための非常に優れた node.js ライブラリ「async」があります。この特定の問題については、 https://github.com/caolan/async#forEachシリーズのバージョンを使用し、 makediffbotAPIcall に少し変更を加えると、探しているとおりに機能するようになるため、ここに解決策があります

async.forEachSeries(out.items,function(item,callback){
makediffbotAPIcall(item,out.items,function(object){
//here you will get either object or null
callback();
}),function(err){
// this will be called when all array items will get processed
})

function makediffbotAPIcall(item, array, callback) {

var url_to_send_diffbot = "string of url here"


request(url_to_send_diffbot, function (error, response, body) {
    if (!error && response.statusCode == 200) {
        var article_object = JSON.parse(body)       
        return callback({"Title": article_object.title, "Url":article_object.url})

    }
    else
        return callback(null);
})
}

makediffbotAPIcall の 2 番目のパラメーターについてはよくわかりません。完全な配列を渡す必要があると思います。そうでない場合は、必要に応じて変更できる場合は、単に配列全体を渡します。

ご不明な点がございましたら、お知らせください。

于 2013-02-09T09:19:01.247 に答える
1

Async.js は開始するのに適した場所です。他にも次のようなものがあります - https://github.com/joyent/node/wiki/modules#wiki-async-flow

ただし、「ブロッキング」コードは node/js ではお勧めできません。これは、シングル スレッドのイベント ドリブン言語です。たとえば、サーバーがリクエストへの反応を停止するため、コードをブロックしたくありません。上記の理由により、ほとんどの asnyc パターンでは、各関数の最後で呼び出す必要がある「next」と呼ばれることもあるコールバック関数を提供するよう求められるため、行内の次の関数が呼び出されます。

于 2013-04-10T06:35:23.420 に答える
0

JSで非同期の問題を処理するときに、すべての無名関数を一時的に移動して名前を付け、それらがいつ渡され、いつ呼び出されるかを明示的に示すと便利なことがよくあります。

function makediffbotAPIcall(item, array) {

    var url_to_send_diffbot = "string of url here"

    var receiveResponse = function (error, response, body) {
        if (!error && response.statusCode == 200) {
            var article_object = JSON.parse(body);   
            var object = {"Title": article_object.title, "Url":article_object.url};
        }
    }

    request(url_to_send_diffbot, receiveResponse);
    return object;
}

したがって、ここにはいくつかの問題があります。まず、リクエストが同期的であったとしても(古いシングルスレッドのJavaScriptの場合、これはひどいことです)、var object内部receiveResponseで使用するため、これは機能しません。そのため、変数はその関数の外部では使用できません。

この特定の問題の場合、最も簡単な解決策は、console.log(object)insideを呼び出すことreceiveResponseです。より複雑なことを行うコードを実際に単純化したと仮定すると、さまざまなパターンを利用できます。各リクエストが前のリクエストの後に順番に発生することが重要ですか、それとも並行して実行し、別々にログに記録することは問題ありませんか(おそらく順序が狂っています)?基本的に、コールバックパラメータを追加してその関数をinsideでmakediffbotAPIcall呼び出すか、Promiseオブジェクトを返す必要があります。これは、それらを提供するフレームワーク/ライブラリをすでに使用していない限り、おそらくやり過ぎです。並列および/または順次操作のサポート。objectresponseReceived

質問を読み直しましたが、動作をブロックしたいようです。再帰を使用した純粋なJSソリューション(libは不要= P)を次に示します。

var i=0;
var callNext = function(object){
    if(i<out.items.length) {
        makediffbotAPIcall(out.items[i], callNext);
    }
    console.log(object);
    i++;
}

callNect("nothing to log for first obj");

function makediffbotAPIcall(item, array, callback) {

    var url_to_send_diffbot = "string of url here"

    var receiveResponse = function (error, response, body) {
        if (!error && response.statusCode == 200) {
            var article_object = JSON.parse(body);   
            var object = {"Title": article_object.title, "Url":article_object.url};
            callback(object);
        }
    }

    request(url_to_send_diffbot, receiveResponse);
}

これは多少の整理で行うことができます(再帰の基本ケースは扱いにくいです)が、必ずしもライブラリが必要なわけではありません;)

于 2013-02-08T22:07:03.087 に答える
0

async.jsライブラリのforEachSeries(arr、iterator、callback)が必要です。

それが行うことは、それが重複しない連続的な方法でarrを反復することです。繰り返し実行されるタスクに最適です。すべての反復が終了すると、コールバックが呼び出されます。最良の部分は、コールバックの手間をかけずにきれいに実行できることです。

async.jsから他の関数​​を試す必要があります。それは素晴らしいライブラリであり、非常に便利です。

于 2013-02-08T22:07:18.173 に答える