0

考虑以下情况:

为了在后端处理大量工作,我将数据发送到接口并等待结果数据返回。因此,ajax 调用非常完美。因为不知道以什么顺序接收结果,并且我需要按特定顺序显示结果才能显示任何内容,如果所有发送的任务都正确返回,我将只调用一个函数。这可以通过一个简单的(减少的,不精确的)信号量变量来完成,该变量计算发送了多少任务。

    var tasks = 0;

    do {
    // things to prepare
    tasks++;

    $.post("foo.php",data, function(data) {
    tasks--;
    foo(data); 
});

    }while(thereIsMore);

    foo(data) {

    // push data to array
    // sort the array

    if(tasks == 0)
     processResults(array);

    }

Javascript 被称为单任务,而不是多任务。我真的可以说,在访问数组和任务计数器时不可能有任何互斥的情况,因为它永远不会发生?我对异步行为有点困惑,可能会想到可以给出赛车情况的场景?

一个例子(我的理解是):

3 在非常短的时间内发送和接收的任务。因此,所有响应都以一种调度方式处理。任务 1 已检查(如果任务 == 0)并且它是错误的。任务 2 在检查任务之前暂停一条指令,任务 3 现在作为成功处理程序执行。任务 3 现在减少任务,其值为 0。任务 3 暂停,任务 2 恢复。任务 2 检查 if(tasks==0) 和地狱是的......它是零。它开始处理,但并非所有数据都在数组中并已排序。

我对您的意见或知识非常感兴趣,如果这完全是不可能发生的疯狂的事情。请分享您的知识:-)

4

3 回答 3

1

一次只能运行一个 ajax 响应函数,并且它将在运行下一个之前运行完成。您不必担心同时访问您的 javascript 变量 - 它不会发生。浏览器中的 Javascript 是真正的单线程(Web Workers 除外,但这不是我们在这里讨论的内容)。

Javascript 使用事件队列。当像 ajax 调用这样的异步操作完成时,它会在事件队列中放入一个条目。如果当前没有 javascript 正在执行,则立即触发该事件(并调用 ajax 回调)。如果某些 javascript 当前正在执行,它只会继续执行。当 javascript 完成一个线程的执行时,它会检查事件队列中是否还有其他东西在等待。如果有,它会处理该事件。这与鼠标事件、键盘事件、计时器事件、ajax 完成事件等的工作方式相同。

仅当当前执行线程完成时才处理下一个事件。

如果您想知道所有 ajax 调用何时完成,您可以像在示例代码中一样记录到目前为止已完成的 ajax 调用数量。在每个完成函数中,您更改完成计数并比较其值以查看是否全部完成。如果数字表明所有这些都已完成,那么您可以进行最后的操作。如果它们还没有全部完成,那么您存储数据并且什么都不做,因为最后一个成功处理程序将看到它们都已完成并启动您的最终操作。

于 2012-08-30T06:14:34.520 回答
0

您也可以只使用带有延迟的 JQuery 的“ when() ”方法。

...或者,Underscore 的“ after() ”函数。

这两种方法都提供了一种非常简单的方法来跟踪多个异步请求何时返回。

于 2012-08-30T06:31:06.240 回答
0

这样的竞速条件永远不会出现在 javascript 中。javascript中有一个叫做Run-to-Completion的东西,它确保如果代码正在执行,它会在任何其他(异步)代码运行之前完全执行,因此不会出现并发问题。

有关更多详细信息,请参阅为什么 javascript 中没有并发控制工具。

于 2015-07-17T08:48:24.540 回答