簡體   English   中英

數組保持按隨機順序輸出-推

[英]Array keeps outputting in random order - Push

我似乎無法弄清楚。

首先,我調用帶有無線電列表的API,然后檢查API中存在多少個無線電。

然后,我根據radio.length的長度使用“ for循環”調用另一個API,並將數據推送到數組中。

這是我使用(Angular JS)的代碼

var radioShows = [];

$http.get('http://api.example.com/radios/').success(function(results) {

        var totalRadioLength = [];

        for (i = 0; i <= results.length; i++) {

            totalRadioLength.push(i);
            console.log(totalRadioLength) // Outputs 7

            $http.get('http://api.example.com/radioshows/fr/radio/' + results[i].id + '/?day=' + x + '').success(function(resultShows) {

                if (resultShows.success === false) {
                    // console.log('No')
                } else {
                    // console.log('Yes')
                    radioShows.push(resultShows);

                }
            })
        }
 })

這似乎很好用,除了每次我的數組radioShows都以隨機順序出現。 根據第一個API調用的順序獲取數組輸出的最佳方法是什么?

之所以以無法預測的順序獲得結果,是因為您按照響應到達的順序將它們放入數組中,並且不能保證請求按照發送它們的順序完成。 根據輸入數據的索引將結果放入數組中。 您可以使用一個函數來創建一個范圍,在該范圍中,每個迭代都獲得自己的變量i

for (i = 0; i <= results.length; i++) {

  (function(i){

    totalRadioLength.push(i);
    console.log(totalRadioLength) // Outputs 7

    $http.get('http://api.example.com/radioshows/fr/radio/' + results[i].id + '/?day=' + x + '').success(function(resultShows) {

      if (resultShows.success === false) {
        // console.log('No')
      } else {
        // console.log('Yes')
        radioShows[i] = resultShows;
      }

    });

  })(i);

}

如前所述,您的http請求同時啟動,因此解析在不同的時間進行。 最簡單的解決方案是同步發出http請求,但這是不現實的,但是有一種方法可以等待所有異步調用完成然后處理它們。

答應救援! 使用promise,您可以啟動所有http請求,但是等待它們完成后再處理它們。 但是,這會將代碼的輸出更改為一個承諾,因此,需要調用此代碼以使用返回的承諾。

var getRadioShows = function() {
    // Create a promise that will resolve when all results have been compiled.
    var deferredResults = $q.defer();

    // Create an array that will store all of the promises
    //   for the async http requests
    $http.get('http://api.example.com/radios/').success(function(results) {

        var deferredHttpCalls = [];
        for (i = 0; i <= results.length; i++) {
            var deferredRequest = $q.defer();
            $http.get('http://api.example.com/radioshows/fr/radio/' + results[i].id + '/?day=' + x + '').success(function(resultShows) {
                if (resultShows.success === false) {
                    // I am guessing this is not a failure case.
                    // If it is then you can call deferredRequest.reject('Request was not successful');

                    deferredRequest.resolve();
                } else {
                    deferredRequest.resolve(resultShows);
                }
            }).error(function() {
                // reject this request and will also cause
                //   deferredResults to be rejected.
                deferredRequest.reject(err);
            });

            // Gather all of the requests.
            deferredHttpCalls.push(deferredRequest);
        }

        // Wait for all of the promises to be resolved.
        $q.all(deferredHttpCalls).then(function(results) {
            // 'results' is an array of all of the values returned from .resolve()
            // The values are in the same order and the deferredHttpCalled array.

            // resolve the primary promise with the array of results.
            deferredResults.resolve(results);
        });
    }).error(function(err) {
        // reject the promise for all of the results.
        deferredResults.reject(err);
    });

    return deferredResults;
}

然后,您將使用像這樣返回承諾的調用。

getRadioShows().then(
    // success function, results from .resolve
    function(results) {
        // process results
    },
    // error function, results from .reject
    function(err) {
        // handle error
    }
)

有關$ q以及所有Promise / A +庫如何工作的更多信息,請參見以下Promise / A +標准: https : //promisesaplus.com/

看來您正在調用$http.get每個循環。 我建議使用i變量而不是push存儲結果。

這樣做的原因是因為您期望每個請求花費的時間都相同,並以正確的順序推送到數組,但是在現實世界中卻並非如此。 這就是為什么該順序顯示為隨機的原因,因為它只能在結果返回時推入數組,而在等待時它已經在進行下一步。

發生這種情況是因為獲取廣播節目的請求以異步模式運行。 也許您可以使用promises同步運行請求,請檢查以下鏈接:

如何在Angular JS中進行同步http請求

您還可以保存每個廣播節目的廣播ID,然后按該ID重新排列結果數組。

radioShows.push({ id: results[i].id, shows: resultShows});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM