0

我有一些任务需要按顺序执行:

function doTasks(tasks, urlDoTask) {
    // Create a deferred for each task by calling doTask().
    var deferreds = $(tasks).map(function (i, task) {
        return doTask(task, urlDoTask);
    }).toArray();

    // return a composite deferred which will wait for each of the doTask requests.
    return $.when.apply($, deferreds);
}

function doTask(task, urlDoTask) {

    return ajax({
        url: getRootDir() + urlDoTask,
        data: { param: task.SomeParam },
        type: 'POST',
        dataType: 'json'
    }).then(function (data) {

        return ok(createObject("status", "ok", "op", "doTask", "task", task, "data", "passed"));
    },
        function (data) {

         return ok(createObject("status", "fail", "op", "doTask", "task", task, "data", "failed"));
        });
}

function ok() {
    return newPromise("resolve", arguments);
}

function newPromise(type, args) {
    return $.Deferred(function (dfd) {
        dfd[type].apply(dfd, args);
    }).promise();
}

function createObject() {
    var ob = {};

    // copy all the arguments name/value pairs into the object
    for (var i = 0; i < arguments.length; i += 2) {
        var n = arguments[i];
        var v = arguments[i + 1];

        ob[n] = v;
    }
    return ob;
}

如何修改此代码以使每个 doTask 按顺序执行?我曾考虑过使用 jquery 队列,但如何在这里申请?也许做类似的事情:

    var deferreds = $(tasks).map(function (i, task) {
        $({}).queue(doTask(task, urlDoTask));
    }).toArray();

并且一旦每个任务都完成了下一步()?

4

2 回答 2

1

我更喜欢看起来简单得多的东西。只需从前一个的成功处理程序开始下一个 ajax 调用。

function processTasks(tasks, urlDoTask)

    var index = 0;
    function nextTask() {
        if (index < tasks.length) {
            $.ajax({
                url: getRootDir() + urlDoTask,
                data: { param: tasks[index].SomeParam },
                type: 'POST',
                dataType: 'json',
                success: function(result) {
                    // process ajax results here

                    // do next ajax call
                    ++index;
                    nextTask();
                }
            });
        }
    }
    // start first ajax call
    nextTask();
}

仅供参考,我假设这是您从每个连续的 ajax 调用中tasks获取的项目数组。.SomeParam如果不是这样,请描述是什么tasks

于 2013-11-03T20:28:58.210 回答
1

我解决这类问题的方法是在完成后让函数自己调用,只需碰撞一个参数即可将递归转换为迭代。

假设您想按顺序 ping N 个 url(可能是一个糟糕的例子,但仍然有效)。

function pingURL(index) {
    if(index>=urlArray.length) {
        return 'Done';
    } else {
        theURL=urlArray[index];
        jQuery.ajax({
                    url:...
                    data: {urltoPing:theUrl}
                   }).done(function(response) {
                       otherFunctions(response);
                       index=index+1;
                       pingUrl(index);
                   });

    }
}

pingURL(0);
于 2013-11-03T20:29:13.387 回答