【问题标题】:Understanding asynch behaivor of javascript with an example通过示例了解 javascript 的异步行为
【发布时间】:2023-04-10 01:54:02
【问题描述】:

我是 javascript 的新手,我正在尝试了解它的异步性质。为此,这是我的示例代码:

  $("#calculate-similarity").click(function(){

        // assume input is an array whose length is larger than 0
        var requestData={"uris":input,"limit":100};
        client=new Ajax(requestData);
        alert('inside .click function');

    })

Ajax=function(requestData){

    alert('inside ajax');
    $.ajax({
        url: 'http://localhost:8080/',
        type:'POST',
        dataType: 'json',
        contentType: 'application/json',
        data: JSON.stringify(requestData),
        xhrFields: {
            withCredentials: true
        }
    }).done(function(data) {
        $("#ws-results").children().detach();
        $("#ws-results").append('<table id="my-final-table"><thead><th>fname</th><th>furi</th><th>sname</th><th>suri</th><th>similarity</th></thead><tbody></tbody></table>');
        $('#my-final-table').dynatable({
            dataset: {
                records:data
            }
        });      
    });
}

现在,在上面,我正在创建 new Ajax() 并在其中创建一个 ajax 请求。据我所知它的异步事件。因此,我认为,这个请求应该首先完成,然后我的其他 javascript 行 (alert('inside .click function')) 应该被执行。换句话说,我希望:

1) alert inside ajax
2) show my datatable on the browser
3) alert inside .click function

但是,我得到了以下命令:

1) alert inside ajax
2) alert inside .click function
3) show table on the browser

那么,你建议我如何理解这些概念?我对 c++ 和 java 等多种编程语言有扎实的背景,但这是我第一次接触 web 开发和 javascript。

编辑

如果我像下面这样修改我的 .click 函数,你是说首先总是会打印 10000 次 hello 然后显示表格吗?或者表格会显示在记录中间的某个地方?我的意思是当响应到来时,引擎应该先等待才能显示它?

修改后的代码:(让我们删除所有的警报语句

$("#calculate-similarity").click(function(){

            // assume input is an array whose length is larger than 0
            var requestData={"uris":input,"limit":100};
            client=new Ajax(requestData);
                for(var z=0;z<10000;z++){
                    console.log(z+'hi!');
                 }

        })

【问题讨论】:

  • 异步意味着它将乱序完成。按照您建议的顺序期望它是同步的。如果您有 C++/Java 方面的背景,我想一个简单的类比(虽然实际上并不正确)是认为 Ajax 在单独的线程上运行。代码立即返回,不等待结果。
  • @dman2306 实际上你是对的。我有点困惑。您知道我可以用来理解这些概念的任何好的资源吗?
  • 如果你熟悉 Java 中的 Swing,想想当你创建一个窗格对象(任何窗格都可以)时,它会立即在内存中发生,但是当你想对其调用 paint 时,它会被推送到 Swing 线程并安排在稍后执行。与您的 Ajax 对象和本机 ajax 请求对象类似的概念(不涉及线程)。

标签: javascript jquery ajax asynchronous


【解决方案1】:

据我所知它的异步事件。因此,我认为,这个请求应该首先完成,然后我的其他 javascript 行应该被执行。

这与它的意思完全相反。

Ajax 函数将运行。它将触发 HTTP 请求。 Ajax 函数将完成。 alert 将运行。

在未来的某个时间点,HTTP 响应将到达,done 事件处理程序将触发。


这与以下原理完全相同:

alert(1);
$("#calculate-similarity").click(function(){ alert(2); });
alert(3);

JavaScript 在触发 alert(3) 之前不会等待您点击计算相似度。


如果我像下面这样修改我的 .click 函数,你是说首先总是会打印 10000 次 hello 然后显示表格吗?或者表格会显示在记录中间的某个地方?我的意思是当响应到来时,引擎应该先等待才能显示它?

JavaScript 不会为了执行不同的(事件处理程序)函数而中断正在运行的函数。它会等到不忙时再去寻找事件。

【讨论】:

  • 我已经编辑了我的问题。请你再检查一遍好吗?
  • 再次感谢您,据我从您编辑的答案中了解到,首先应该完成循环,然后应该显示返回的响应。 @昆汀
【解决方案2】:
  1. new Ajax 是对象实例化,它是同步的。因此,您会得到inside ajax 作为第一个结果,因为它发生在您的 Ajax 对象被实例化时,不要与 Ajax 请求被触发时混淆。
  2. alert 是同步执行的,所以这是你得到的第二件事。
  3. $.ajax 包裹在 XMLHttpRequest 周围,负责触发实际的 ajax 请求,是代码中唯一的异步部分,其结果封装在 done 中,是您最后得到的。

换句话说,我认为混淆来自于你引入了另一个抽象层new Ajax(),它提供了很少的实际价值和很多混淆:P。 inside ajax您的 Ajax 对象的实例化中发出信号,而不是触发实际请求。

【讨论】:

  • 感谢您的回复,但我仍然无法理解那部分:在client=new Ajax(requestData); 行,我的Ajax 对象初始化已经开始。 (这就是为什么出现内部 ajax 警报的原因)。在那之后,里面的 .click 函数怎么会出现在表格之前?
  • 你的ajax对象不是浏览器的ajax请求对象。
  • @zwlayer 如果你熟悉 Java 中的 Swing,想想当你创建一个窗格对象时,它会立即发生,但是当你想对其调用 paint 时,它会被推送到 Swing 线程并计划稍后执行。
  • 感谢您的所有努力。当我读到在未来的某个时间点,HTTP 响应将会到达并且 done 事件处理程序将会触发。 在 Quentin 的回答中,一切都变得更加清晰。我知道 JS 不会在 my Ajax 函数内部等待结果来自网络。
  • 欢呼@zwlayer 不过,我对我的 Swing 类比非常满意。下次要拉那个:D
【解决方案3】:

我会尽力解释。将此更多地视为一个类比,它并不完全是正在发生的事情,但我认为它可能会帮助您理解:

alert('inside ajax'); - 这是一个阻塞调用,它将运行并等待您单击确定。

然后,当您调用 Ajax 时,您实际上是在说“有机会时发出这个 Web 请求,并在它完成时调用我的 done 方法。”那是网络操作。它可能在 1 秒内完成,可能需要很多秒。这不是冻结整个浏览器,而是“在后台”完成的。所以这使得 UI 保持响应。在未来的某个时刻,网络请求将完成。当它完成时,您在done 中指定的函数将被调用以通知您它已完成。将 Ajax 请求视为将其添加到队列而不是实际连接到网络。当浏览器访问它时,它将执行您的请求并等待服务器响应。当它发生时,它会向您发出信号让您知道。

接下来是alert('inside .click function');,它会显示警报和阻止。

就像我说的,这不是对正在发生的事情的技术准确描述,但我希望它可以帮助您理解它的原理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-06
    • 2017-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多