有没有办法强制中止正在执行的JavaScript(或jQuery)函数?

时间:2016-05-22 06:15:09

标签: javascript jquery

<script>
var fn = function(url){
    // bla bla bla...
};
</script>

<input type="button" onclick="fn()" value="Execute">
<input type="button" onclick="???" value="Abort">

如上所述,当用户点击“执行”按钮时,将执行fn()功能。

假设fn()功能将运行一个非常很长一段时间,如果用户想要中途停止执行此功能,我该怎么办?

5 个答案:

答案 0 :(得分:4)

JavaScript中的函数是阻塞 - 这意味着当函数运行时,所有[1]都会冻结。屏幕不会重绘,不会处理鼠标点击,也不会处理键盘事件。

在功能完成之前没有任何事情发生。

解决此问题的唯一方法是使用void insert(Node*& node, int data) 编码以小的一口大小的块运行您的代码。

有许多工具可供使用,包括:

我建议您查看setTimeout工具,然后询问有关如何使您的功能无阻塞的其他问题。

[1]为了讨论的目的

答案 1 :(得分:0)

您可以设置第二个input type="button" disabled属性;创建一个引用延迟对象的变量;创建延迟对象时,在disabled删除input type="button"属性;点击第二个deferred.reject(),以new Error()为参数调用input type="button"

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<script>
var ajax, d;
function fn(event, url){
    // bla bla bla...
  ajax = new $.Deferred(function(dfd) {
    d = dfd;
    $("input[value=Abort]").removeAttr("disabled")
     setTimeout(function() {
       dfd.resolve("complete")
     }, Math.random() * 10000)
  });
  ajax.then(function(complete) {
    console.log(complete)
  }, function(e) {
       console.log(e)
  })
};
</script>

<input type="button" onclick="fn(event)" value="Execute">
<input type="button" onclick="d.reject(new Error('aborted'))" value="Abort" disabled>

答案 2 :(得分:0)

一般不会,你不能。至少我不认为你可以。但是你可以而且应该以不阻止你的用户界面的方式编写你的功能。 UI和JavaScript都使用一个线程,因此如果在JavaScript中运行很长的函数,用户就无法使用UI。所以无论如何都不会处理点击事件。相反,您想要的是使用setTimeout(或在内部使用它的某个库)将长计算拆分为多个部分。 然后检查中止情况。这种事情的非常简单的例子在下面的片段中。

&#13;
&#13;
var abort = false;
var target = document.getElementById('target');

function veryLongFunction(step) {
  step = step || 0;
  
  if (abort) {
    return;
  }
  
  target.innerHTML = target.innerHTML + '<br>' + step;
  
  window.setTimeout(veryLongFunction.bind(null, step + 1), 1000);
}

document
  .getElementById('start')
  .addEventListener('click', function () {
    veryLongFunction(0);
  });

document
  .getElementById('stop')
  .addEventListener('click', function () {
    abort = true;
  });
&#13;
<button id="start">start</button>
<button id="stop">stop</button>
<div id="target"></div>
&#13;
&#13;
&#13;

答案 3 :(得分:0)

您可以将功能分解为零件并使用计时器停止零件。计时器分解事件循环以允许点击按钮来更新变量,例如设置abort = true。

在分解函数中,检查变量是否更新以指示您应该中止。如果是,则返回,否则继续运行该功能。

有多种方法可以中止ajax请求。您可以为onclick事件设置一个打开请求池和一个函数来中止它们。

使用jquery这样的东西:

var ajaxPool = [];

$.ajaxSetup({
    beforeSend: function(jqXHR) {
        ajaxPool.push(jqXHR); // keep track of active requests
    },
    complete: function(jqXHR) {
        var index = ajaxPool.indexOf(jqXHR);
        if (index > -1) {
            ajaxPool.splice(index, 1); // remove completed requests
        }
    }
});

//the function to run onclick:

function abortAllAjax () {
    for (var i = 0; i < ajaxPool.length; i++) {
        ajaxPool[i].abort();
    }
    ajaxPool = [];
};

答案 4 :(得分:-1)

我很确定没有,但如果有,那就错了。

在单线程语言中,正确的解决方案可能是在完成某些工作后检查停止标志。如果标志(属性或全局变量)变为真,则算法会执行任何必须执行的操作以停止并返回函数。

如果算法很长或包含循环,它将如下所示:

var running=true;
var fn = function(url){
    while(1) {
        if(!running) return;
        // bla bla bla...
    }
};

如果你的意思是一个需要很长时间才能完成的ajax调用,你可以用abort()中止它:

var xhr=$.ajax(...);
...
xhr.abort();