2017-10-27 16 views
-1

forループでAJAX呼び出しを行う必要があります。私は、配列内のレスポンスを格納していて、配列の要素が順番に並んでいるので、呼び出しが順番に行われる必要があります。私はasync: falseのために行っていました。彼らのどれも働かなかった。 async: falseを作ることは、私が知っている本当に悪い考えですが、応答を順番に取得する代わりに何ができますか?asyncの代替:false

追加情報:配列をレンダリング要素にマッピングしていますので、試したメソッドのほとんどが「未定義のマップを読み取れません」というエラーが表示されました。私は代替として実装しようとしたが、それは仕事と私は未定義

//initialize index counter 
      var i = 0; 
      var that = this; 
      function next() { 
       $.ajax({ 
        async: true, 
        "crossDomain": true, 
        "url": that.state.current_auto_video_jobs_urls[i], 
        "method": "GET", 
        "headers": { 
         Authorization: "Token " + that.props.token_Reducer.token 
        }, 
        success: function(response, textStatus, jQxhr){ 
         ++i; 
         if(i >= that.state.current_auto_video_jobs_urls.length) { 
          // run function here as its the last item in array 
          console.log("i reached last value") 
          that.setState({current_auto_video_jobs: auto_video_jobs_array}) 
          console.log("current jobs are" + that.state.current_auto_video_jobs) 
         } else { 
          // do the next ajax call 
          auto_video_jobs_array.push(response) 
          next(); 
         } 
        } 
       }); 
      } 

      // start the first one 
      next(); 

のマップを読み取ることができないというエラーを投げていなかった

auto_video_jobs_array = []; 
     for (var i = 0; i < this.state.current_auto_video_jobs_urls.length; i++) { 
      this.get_auto_video_jobs_array(i) 
     } 

get_auto_video_jobs_array(i) { 
     var that = this; 
     var settings_3 = { 
      "async": false, //this is made false to get array element in right sequence 
      "crossDomain": true, 
      "url": that.state.current_auto_video_jobs_urls[i], 
      "method": "GET", 
      "headers": { 
       Authorization: "Token " + that.props.token_Reducer.token 
      }, 
      success: function (response, textStatus, jQxhr) { 
       console.log("success") 
       console.log("value of i is " + i) 
      }, 
     } 

     $.ajax(settings_3).done((response) => { 
      auto_video_jobs_array.push(response) 
      if (i == that.state.current_auto_video_jobs_urls.length - 1) { 
       console.log("i reached last value") 
       that.setState({current_auto_video_jobs: auto_video_jobs_array}) 
       console.log("current jobs are" + that.state.current_auto_video_jobs) 
      } 
     }); 
    } 

この何:ここ

は、私が現在やっているものですインクリメンタルシーケンスで応答を得る方法で非同期呼び出しを行う方法が必要です。プロミスが提案する一つの選択肢です。私はそれが初めてです。それが方法ならそれをどう実装するのですか?

+0

あなたが実際に順次リクエストを送信する必要がありますか?または結果が元の順序になるようにするだけですか? –

+0

@KevinB説明に基づいて、彼らは元の順序である必要があるようです。 – JLRishe

答えて

-2

基本的に、一連の非同期タスクを連続して実行する必要があります。言い換えれば、対応するライブラリからasync.seriesメソッドの種類を持つ必要があります。同様の機能を提供するstandalone packageがあります。ご自身のソリューションのベースとして、(かなり小さい)sourcesを使用することができます。ここで

が少しNode.jsの環境に固有のクリーンアップコードでasync-seriesソースのバージョンに変更されます。このような機能を有する

/** 
* @author Hugh Kennedy 
* @url https://github.com/hughsk/async-series 
* @license MIT 
*/ 
function series(arr, ready, safe) { 
    var length = arr.length, orig; 
    var nextTick = 'undefined' !== typeof setImmediate ? setImmediate : setTimeout; 

    if (!length) { 
     return nextTick(ready, 1) 
    } 

    function handleItem(idx) { 
     arr[idx](function (err) { 
      if (err) return ready(err) 
      if (idx < length - 1) return handleItem(idx + 1) 
      return ready() 
     }) 
    } 

    if (safe) { 
     orig = handleItem 
     handleItem = function (idx) { 
      nextTick(function() { 
       orig(idx) 
      }, 1) 
     } 
    } 

    handleItem(0) 
} 

を使用すると、タスクのリストを渡すためにそれを実行し、埋めるために簡単なはずあなたの配列は、順番に実行されることが保証されています。

+0

私はこれの行を理解していません。 – ApurvG

-2

これを約束すると非常に簡単です。 IEが組み込まれていないことを約束のためのサポートに注意してください、しかし、あなたはブルーバードのようなライブラリを使用してIEでそれらをサポートすることができます。

var that = this; 
var auto_video_jobs_array; 

// wait for all promises 
Promise.all(this.state.current_auto_video_jobs_urls.map(function (url) { 
    // map each url to a promise for the result of querying that URL 
    var settings_3 = { 
     "crossDomain": true, 
     "url": url, 
     "method": "GET", 
     "headers": { 
     Authorization: "Token " + that.props.token_Reducer.token 
     } 
    }; 

    return $.ajax(settings_3); 
    })) 
    .then(function(results) { 
    // results is an array of all the query results, in an order matching 
    // the original array 
    auto_video_jobs_array = results; // you might not need auto_video_jobs_array 
             // anymore, but just in case... 
    that.setState({ 
     current_auto_video_jobs: results 
    }); 
    });