jQuery使用ajax调用延迟循环

时间:2015-04-07 05:46:36

标签: javascript jquery asynchronous jquery-deferred deferred

我目前有一个应用程序依赖于所有正在检索的数据,然后继续进一步的代码。

有一个主要功能" _update()"包含一个循环,这个循环调用_getData()。我需要" _update()"在收到所有数据时将变量设置为true。

这就是我所拥有的:

DataCollection.prototype._update = function () {
    var _self = this;
    var _itemsResponded = 0;
    var itemData = [];

    if (_self._ready) {
        _self._ready = false;

        this.collection.forEach(function (item, index) {
            _self.apiData.id = item.id;

            var ajaxPromise = _self._getData();
            ajaxPromise.done(function(data){
                itemData[index] = data;
                _self._itemsResponded++;
            });
        })

        if (_self._itemsResponded === _self.collection.length) {
            _self._ready = true;
            console.log(itemData);
            console.log('done');
        }
    }
}

DataCollection.prototype._getData = function () {
    var _self = this;

    var ajaxPromise = $.ajax({
        url: 'ajax.php',
        data : _self.apiData,
        dataType: 'json'
    });

    var dff = $.Deferred();
    ajaxPromise.then(function(data) {
        dff.resolve(data);
    }, function(){
        dff.reject();
    });

    return dff.promise();
}

根据我的理解,_getData函数正常工作。它是_update中的.forEach,它不能按预期工作。我以为.forEach是同步的吗?

1 个答案:

答案 0 :(得分:0)

由于forEach()方法的内容是异步的,foreach循环将在所有ajax请求完成之前完成执行,所以你的检查应该进入完成回调内部,如

DataCollection.prototype._update = function () {
    var _self = this;
    var _itemsResponded = 0;
    var itemData = [];

    if (_self._ready) {
        _self._ready = false;

        this.collection.forEach(function (item, index) {
            _self.apiData.id = item.id;

            var ajaxPromise = _self._getData();
            ajaxPromise.done(function (data) {
                itemData[index] = data;
                _self._itemsResponded++;

                if (_self._itemsResponded === _self.collection.length) {
                    _self._ready = true;
                    console.log(itemData);
                    console.log('done');
                }
            });
        })
    }
}

您可以使用$ .when()将其简化为

DataCollection.prototype._update = function () {
    var _self = this;
    var _itemsResponded = 0;
    var itemData = [];

    if (_self._ready) {
        _self._ready = false;

        var promises = $.map(this.collection, function (item, index) {
            _self.apiData.id = item.id;
            return _self._getData();
        });

        $.when.apply($, promises).done(function () {
            var itemData = $.map(arguments, function (arr, idx) {
                return arr[0];
            })
            _self._ready = true;
            console.log(itemData);
            console.log('done');
        })
    }
}

DataCollection.prototype._getData = function () {
    var _self = this;

    var ajaxPromise = $.ajax({
        url: 'ajax.php',
        data: _self.apiData,
        dataType: 'json'
    });
    return ajaxPromise;
}