<script>
var fn = function(url){
// bla bla bla...
};
</script>
<input type="button" onclick="fn()" value="Execute">
<input type="button" onclick="???" value="Abort">
如上所述,当用户点击“执行”按钮时,将执行fn()
功能。
假设fn()
功能将运行一个非常很长一段时间,如果用户想要中途停止执行此功能,我该怎么办?
答案 0 :(得分:4)
JavaScript中的函数是阻塞 - 这意味着当函数运行时,所有[1]都会冻结。屏幕不会重绘,不会处理鼠标点击,也不会处理键盘事件。
在功能完成之前没有任何事情发生。
解决此问题的唯一方法是使用void insert(Node*& node, int data)
编码以小的一口大小的块运行您的代码。
有许多工具可供使用,包括:
async
并保留数组索引
我建议您查看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(或在内部使用它的某个库)将长计算拆分为多个部分。 然后检查中止情况。这种事情的非常简单的例子在下面的片段中。
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;
答案 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();