2017-01-19 7 views
0

私のルートadd-usersの1つでPOSTリクエストを行っています。成功と呼ばれる配列を作成しました。要求が応答を返すと、次のAPI呼び出しをトリガーします。NODE - 次回のAPIコールをトリガーする前に1回のAPIコールが完了するまで待つ

APIリクエストをすぐに送信すると思われるため、現時点では機能しません。私は解決策は、最初の応答が応答を返して終了し、次のAPI呼び出しをトリガするまで待つことだと思います。

この仮定は正しいですか?もしそうなら、誰もこれを実装する方法をアドバイスできますか?私は使用しようとしました.on('end'....

下記の私のコードを見てください。

app.get('/add-users', function (req, res) { 

    var success = []; 
    var count = 0; 
    for(var i = 0; i < users.length; i++) { 
     var name = users[i].userId; 
     request({ 
      url: url, 
      headers: { 
       'Authorization': 'Bearer ' + users[i].accessToken, 
       'Content-Type': 'application/json' 
      }, 
      method: 'PUT', 
      json: true 
     }, function(err, resp, body){ 
      if (!err && resp.statusCode === 200) { 
       success.push(name); 
      } 
     }) 
     .on('end', function(){ 
      console.log('this is the end'); 
      count++; 
      if(count === users.length) { 
       res.json(success); 
      } 
     }); 
    } 
}); 

答えて

1

クラシック!私は最初にノードを扱っていた時にもこの問題を抱えていました。

レムは、最初にコピーして、コードの一部を説明します。他の言語(例えばルビー)とは対照的に

app.get('/add-users', function (req, res) { 
    // [...] 
    for(/* user in users */) { 
     request(/* [...] */) 
     .on('end', function(){ 
      console.log('this is the end'); 
      count++; 
      if(count === users.length) { 
       res.json(success); 
      } 
     }); 
    } 
}); 

ノードは、I/Oを非ブロックありません。これは、(HTTPリクエストを作成するなどの)ほぼすべてのI/O操作を非同期的に実行することを意味します。基本的に、リクエストを開始すると、応答を待つことはありません。

start loop 
    make request 
    handle response 
    make request 
    handle response 
    make request 
    handle response 
end of loop 

ワン:

start loop 
    make request 
    make request 
    make request 
end of loop 

... a little later 
handle response 
handle response 
handle response 

は、私はあなたが欲しいものはこのようになっていることを前提としています。あなたのループでは

は、これはその応答を待たずにすべての要求を1つずつを発射することを意味します私がノードのノンブロッキングな性質を取り戻し、逐次的な要求を行うことがこのような再帰関数を書くことであることを発見しました:

function getAllUsers(users) { 
    function getOneUser(users) { 
     let user = users.pop(); 
     request(/* [...] */) 
      .on('end', function() { 
       console.log("done with ONE user"); 
       if(users.length) { // do we still have users to make requests? 
        getOneUser(users); // recursion 
       } else { 
        console.log("done with ALL users"); 
        res.json(success); 
       } 
      }); 
    } 

    // make a copy of the original users Array because we're going to mutate it 
    getOneUser(Array.from(users)); 
} 

上記の処理は、1人のユーザーに対して1つのリクエストを行い、応答が到着したときに別のリクエストを送信します。

こちらがお役に立てば幸いです。

+0

これを今見てみましょう。感謝のコスタス –

+0

@phantomは例外をスローしますか? (ごめんなさいあなたのコメントを間違って削除しました) – Kostas

+0

そのすべてがうまく動作していますが、私のエラーでした。素晴らしい解決策 –

0

ここでは通常、複数のリクエストを連鎖させる方法を示します。ループ内で非同期関数を呼び出そうとすると、コードを書いたように動作しません。代わりに、最初のリクエストのコールバックで次のリクエストを呼び出すことをおすすめします。

//set index 
var index = 0; 
function callAPI(user) { 
    //increment index 
    index++ 
    request({request:object},function(err, res){ 
     if (index <= users.length) { 
     callAPI(users[index]) 
     } 
    }); 
} 
//call function with 0 index 
callApi(users[0]) 

また、上記のコードでconsole.log(name)を使用すると、問題が表示されます。

関連する問題