簡體   English   中英

AngularJS Promise返回空數組

[英]AngularJS Promise Returns Empty Array

我在工廠中有以下代碼:

  getAyahsByJuz: function (juzIndex) {
        var response = [];
        var promises = [];

        var self = this;
        var deferred = $q.defer();
        $timeout(function () {
            $http.get('data/quran.json').success(function (data) {
                var ayahs = Quran.ayah.listFromJuz(juzIndex);
                angular.forEach(ayahs, function (value, key) {
                    var promise = self.getVerse(value.surah, value.ayah).then(function (res) {
                        var verse = {
                            surah: value.surah,
                            ayah: value.ayah,
                            text: res
                        };
                        response.push(verse);
                    }, function (err) {
                        console.log(err);
                    });
                    promises.push(promise);
                });
            });
        }, 30);

        $q.all(promises).then(function() {
            deferred.resolve(response);
        });

        return deferred.promise;
    },

請注意, verse對象正常返回后,一切正常。 但是,當我在使用.then(res)的控制器中使用它時。 res返回[]而不是填充有詩句對象的數組。

誰能指出原因? 謝謝!

簡短的答案是因為您的$q.all$timeout之前和$timeout嵌入的$http之前運行。 讓我們將原始代碼簡化為相關組件:

getAyahsByJuz: function (juzIndex) {
    var response = [];
    var promises = [];
    var deferred = $q.defer();
    // ...irrelevant stuff that will happen after a $timeout
    // this happens IMMEDIATELY (before $timeout):
    $q.all(promises).then(function() { // wait for empty promise array
        deferred.resolve(response); // resolve with empty response array
    }); // side note: this is a broken chain! deferred.promise can't reject

    return deferred.promise; // send promise for empty array
}

看到問題了嗎? 如果出於某種奇怪的原因,您需要保留該$timeout ,則此修復程序具有大量promise重構,並刪除了受jquery啟發可怕的,非success語法 ):

getAyahsByJuz: function (juzIndex) {
    var self = this;
    // $timeout itself returns a promise which we can post-process using its callback return value
    return $timeout(function () {
        // returning the $http promise modifies the $timeout promise
        return $http.get('data/quran.json').then(function (response) { // you never used this response!

            var versePromises = [];

            var ayahs = Quran.ayah.listFromJuz(juzIndex);
            angular.forEach(ayahs, function (value, key) {
                // we'll push all versePromises into an array…
                var versePromise = self.getVerse(value.surah, value.ayah).then(function (res) {
                    // the return value of this `then` modifies `versePromise`
                    return {
                        surah: value.surah,
                        ayah: value.ayah,
                        text: res
                    };
                });
                versePromises.push(versePromise);
            });

            return $q.all(versePromises); // modifies $http promise — this is our ultimate promised value
            // if a versePromise fails, $q.all will fail; add a `catch` when using getAyahsByJuz!
        });
    }, 30);

}

但是,這里仍然存在巨大的問題……為什么不在任何地方使用$http調用的服務器響應? 第一次電話的意義是什么?

我也發現$timeout非常可疑。 如果您需要它,那么代碼中其他地方可能發生了一些問題。

暫無
暫無

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

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