jQuery $.when.apply不按预期工作

3

我正在尝试使用jQuery的$.when.apply来等待未知数量的请求完成后再调用下一个函数(loadTab)。我认为我使用得很正确,但它明显没有在loadTab()被调用之前等待所有请求完成,所以我不确定哪里出了问题。这是我的代码:

function update(changes) {
    var deferreds = [];

    // must loop over changes and call individual requests
    for(var i = 0; i < changes.length; i++) {
        var direction = changes[i]['direction'];
        var data = changes[i]['data'];

        if(direction == 'add') {
            deferreds.push[add(data)];
        }
        else if(direction == 'edit') {
            deferreds.push[edit(data)];
        }
        else if(direction == 'delete') {
            deferreds.push[delete(data)];
        }
    }

    return $.when.apply($, deferreds); // this when is resolving too soon
}

function add(data) {
    return $.ajax({
        url: 'add',
        data: data,
        method: 'post',
        error: ajaxErrorFcn
    })
    .then(function(response) {
        handleTimeout(response);
    });
}

function edit(data) {
    return $.ajax({
        url: 'edit',
        data: data,
        method: 'post',
        error: ajaxErrorFcn
    })
    .then(function(response) {
        handleTimeout(response);
    });
}

function delete(data) {
    return $.ajax({
        url: 'delete',
        data: data,
        method: 'post',
        error: ajaxErrorFcn
    })
    .then(function(response) {
        handleTimeout(response);
    });
}

// this is the sequence of events I'm trying to sort out
showLoad('#container');
var changes = buildChangesArray();
update(changes)
.then(function(response) {
    if(handleTimeout(response)) {
        // this is executing before the requests triggered by update() are complete
        return loadTab()
        .then(function(response) {
            // do some other stuff
        });
    }
})
.then(function(response) {
    hideLoad('#container');
});

更新:

原始问题已解决(我的.push()调用中有一个错别字,使用了方括号而不是圆括号),但现在我在这段代码中遇到了一个新问题。我需要修改update()函数,先运行删除操作,然后再运行添加和编辑操作。这是我目前的代码,但现在我发现添加和编辑操作开始在删除操作完成之前运行:

function update(changes) {
    var deferreds = [];
    var deletes = [];

    // must loop over changes and call individual requests
    for(var i = 0; i < changes.length; i++) {
        var direction = changes[i]['direction'];
        var data = changes[i]['data'];

        if(direction == 'add') {
            deferreds.push(add(data));
        }
        else if(direction == 'edit') {
            deferreds.push(edit(data));
        }
        else if(direction == 'delete') {
            deletes.push(delete(data));
        }
    }

    // we need to perform all the delete operations first, then the adds/edits
    return $.when.apply($, deletes) // this when is resolving too soon
    .then(function(response) {
        return $.when.apply($, deferreds);
    });
}

array.push 是一个函数,使用标准括号而不是方括号。 - James
@James 谢谢,我甚至没有注意到我在那样做!问题解决了!多么愚蠢的错误 :) - vor
1个回答

2

看起来我找到了自己的解决方案 :)

我认为问题在于将异步调用add()、edit()和delete()推送到数组中时,它们也会在那一点上被调用!这在第一个版本中不是问题,因为只要在调用loadTab()之前完成所有添加、编辑和删除操作,它们的执行顺序并不重要。然而,如果需要在调用任何添加或编辑操作之前调用所有删除操作,则会出现问题,因为在删除操作之前在数组中找到的任何添加或编辑操作都将立即开始运行,而不是等待删除操作。

为了解决这个问题,我将代码更改如下:

function update(changes) {
    var loop = function(deleteOnly) {
        var array = [];

        // must loop over changes and call individual requests
        for(var i = 0; i < changes.length; i++) {
            var direction = changes[i]['direction'];
            var data = changes[i]['data'];

            if(direction == 'add' && !deleteOnly) {
                array.push(add(data));
            }
            else if(direction == 'edit' && !deleteOnly) {
                array.push(edit(data));
            }
            else if(direction == 'delete' && deleteOnly) {
                array.push(delete(data));
            }
        }

        return array;
    };

    // we need to perform all the delete operations first
    return $.when.apply($, loop(true)) // true means only get the deletes
    .then(function(response) {
        return $.when.apply($, loop(false)); // false means only get the adds/edits
    });
}

因此,一旦将请求推入数组中,它们仍会立即开始运行,但这样我们可以分离删除请求以确保它们先完成。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接