Javascript:等待条件为真的非阻塞方式

时间:2012-10-11 14:10:59

标签: javascript sleep wait

我有几个ASP.NET UpdatePanel,每个都有一个AsyncPostBackTrigger绑定到同一个按钮的服务器端点击事件。由于一次只有一个UpdatePanel可以执行此操作,因此我使用.get_isInAsyncPostBack()的{​​{1}}来防止用户在异步回发完成之前能够访问页面的其他部分。

此页面的另一部分需要连续动态更新多个更新面板。由于更新面板使用异步触发器,因此调用PageRequestManager会异常激活。因此,它将快速移动到循环的下一次迭代并尝试更新下一个面板。但是,第二次迭代失败,因为已经有另一个更新面板执行异步回发。

理想情况下,有一种方法可以等到__doPostBack("<%=ButtonName.ClientID %>", 'PanelId');返回false而不会阻止其他客户端活动。

研究让我遇到了很多有问题的人,几乎所有人都被建议使用.get_isInAsyncPostBack()。我不认为这对我有用。我不想在执行函数之前等待指定的时间。我只是希望我的Javascript在另一个脚本运行时等待,最好等到特定条件为真。

我知道很多人可能会建议我重新考虑我的模型。它实际上不是我的模型,而是一个交给我们开发团队的模型,目前这个团队一直处于混乱状态。由于时间限制,重写模型不是一种选择。唯一的选择是使这项工作。我认为,如果我有办法使客户端代码无阻塞地等待,我的问题就会得到解决。

4 个答案:

答案 0 :(得分:28)

在javascript中没有诸如等待或睡眠之类的功能,因为它会阻止浏览器响应。

在你的情况下,我会采用与以下类似的东西:

function wait(){
  if (!condition){
    setTimeout(wait,100);
  } else {
    // CODE GOES IN HERE
  }
}

答案 1 :(得分:13)

调用setTimeout会导致JavaScript调用堆栈填满时,很容易出错。如果你的函数有参数,你需要在setTimeout参数列表的末尾传递这些参数:

function wait(param1, param2){
  if (!condition){
    setTimeout(wait, 100, param1, param2);
  } else {
    // CODE GOES IN HERE
  }
}

如果传递参数或者甚至在函数名称后面包含empty(),它将立即执行并填满堆栈。

// This is the wrong way to do it!    
function wait(param1, param2){
  if (!condition){
    setTimeout(wait(param1, param2), 100); // you'll get max call stack error if you do this!
  } else {
    // CODE GOES IN HERE
  }
}

答案 2 :(得分:2)

此函数调用condFunc,当满足条件时,该函数应返回true。当发生这种情况时,会调用readyFunc。 checkInterval以毫秒为单位设置检查率

       var wait = function(condFunc, readyFunc, checkInterval) {
            var checkFunc = function() {
                if(condFunc()) {
                    readyFunc(); 
                }
                else
                {
                    setTimeout(checkFunc, checkInterval);
                }
            };
            checkFunc();
        };

用法:

       wait(
            function() { return new Date().getSeconds() == 10; }, 
            function() { console.log("Done"); },
            100
        );

打印&#34;完成&#34;当前时间是分钟后的10秒

答案 3 :(得分:1)

我需要放慢一个过程并提出一个有用的小方法。

wait = (seconds) => 
   new Promise(resolve => 
      setTimeout(() => resolve(true), seconds * 1000)
   );

你可以像这样使用它。

doWork = async() => {
   if(await this.wait(3)) {
       // After 3 seconds do something...
   }
}