【问题标题】:window.location not evaluating until entire call stack is processed?window.location 在处理整个调用堆栈之前不评估?
【发布时间】:2014-01-04 19:14:24
【问题描述】:

我有一点 javascript,由一个 HTML 按钮触发,它调用一个函数。这也使用了 Jquery,因此在此过程中也会调用一些底层函数。在我的脚本中,我对 window.location 进行了一些更改,以便与远程系统通信(它应该触发不同的脚本以响应这些调用)。这个 window.location 定义没有使用 HTTP 协议,而是 FMP,一个在我的机器上注册的 FileMaker Pro 协议。

示例代码:

function compareJSON() {
    dataSession=({ //build object for output    });   
    $.each( dataSession.chapters , function( indexC, value ) {  
        //compare objects to some others, testing and changing data
    });
    //Call remote script on other system
    window.location= "fmp://blah.dee.com/Blar?script=SaveJSON&$JSONobject=" + JSON.stringify( dataSession );
   //Call remote script on other system
   window.location="fmp://blah.dee.com/Blar?script=EditJSON";
}

(请记住,由于这是使用 Jquery,因此在运行我的函数之前,只需按下调用此 compareJSON() 函数的按钮即可创建包含 2 或 3 个其他函数的堆栈。但是,即使它被直接调用某种方式,比较函数本身将在堆栈上,因此 window.location 直到该函数结束时才会被评估。)

问题在于,在整个 JS 调用堆栈完成之前,Window.Location 似乎没有被最终确定/设置/发送/任何内容。因此,当我单击启动这些函数调用的按钮时,堆栈会在其上放置一些 Jquery 函数(例如“处理程序”、“默认”、“每个循环”......),然后它会命中我编写的 JS 代码,这又在堆栈中添加了更多的函数调用;然后还有一些更多的 Jquery 函数添加到堆栈中,等等。但是在我的函数中创建的这些堆叠的 window.location 定义实际上并没有触发远程系统,直到我一路通过 JS 调用堆栈并退出所有内容.因此 window.location 仅被定义/设置为函数调用中最后设置的任何内容,而不是包括堆栈中出现的所有干预定义/集。这就像一个变量,在调用堆栈中被多次更改,但最后只被读取一次。

有没有办法强制 window.location 在设置时对其进行评估,而不是等待最后一个设置是什么?

谢谢, J

【问题讨论】:

  • 你能展示你的代码吗?
  • 您可以设置window.location,然后在很短的超时时间内包装您的后续代码,但请注意,设置window.location 通常会吹走整个窗口上下文。总体而言,您要实现什么目标?
  • @Alex:添加了一些示例代码。
  • 您的问题有点令人困惑,所以我不确定这是否相关,但请记住 JS 是一种单线程语言。这意味着函数在运行之前的调用堆栈之前不会被调用。此外,您可能想尝试 iframe 或其他东西,而不是 window.location
  • @Cronk 嗯,我的建议可能没有意义,但正如 Zove Games 所说,JavaScript 环境是单线程的。浏览器容器在遵守对window.location 的更改之前正在等待脚本执行完成。 setTimeout 理念允许您在后续事件循环中继续处理;我不知道这是否适用于您的情况。

标签: javascript jquery callstack window.location


【解决方案1】:

您可能想要使用 iframe:

function callScript(url) {
    var ifr = document.createElement('iframe');
    ifr.src = url;
    // you can even add ifr.onload = function() {doSomething();}; if you want
}

这将允许一次任意数量的调用。

【讨论】:

    【解决方案2】:

    这可能行不通,但超时的想法是改变如下:

    // code code code ...
    window.location = newUrl;
    // more code ...
    

    进入:

    // code code code ...
    window.location = newUrl;
    setTimeout(function() {
      // more code ...
    }, 1);
    

    这允许浏览器在启动计时器处理程序的下一个事件循环之前可以做一些事情的时间间隔。

    【讨论】:

      猜你喜欢
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      • 2015-02-14
      • 2021-05-02
      • 2023-03-09
      • 2015-01-01
      • 2012-05-01
      • 2013-05-02
      相关资源
      最近更新 更多