Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/416.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在浏览器事件上中断繁重计算的模式_Javascript_Multithreading_Performance_Asynchronous_Es6 Promise - Fatal编程技术网

Javascript 在浏览器事件上中断繁重计算的模式

Javascript 在浏览器事件上中断繁重计算的模式,javascript,multithreading,performance,asynchronous,es6-promise,Javascript,Multithreading,Performance,Asynchronous,Es6 Promise,我正在开发一个客户端模拟,它可以动态地进行背景计算和视图刷新。然而,由于模拟始终是实时的,因此CPU在用户输入和编辑时会做很多不必要的工作 我想要实现的是一种在用户事件中终止整个序列的方法 主应用程序中的预期使用情况: var sequence = new Sequence(heavyFunc1, heavyFunc2, updateDom); document.addEventListener("click", sequence.stop) sequence.run() //all the

我正在开发一个客户端模拟,它可以动态地进行背景计算和视图刷新。然而,由于模拟始终是实时的,因此CPU在用户输入和编辑时会做很多不必要的工作

我想要实现的是一种在用户事件中终止整个序列的方法

主应用程序中的预期使用情况:

var sequence =  new Sequence(heavyFunc1, heavyFunc2, updateDom);
document.addEventListener("click", sequence.stop)
sequence.run() //all the heavy computation runs until told to stop
web worker中的预期使用情况:

var sequence =  new Sequence(heavyFunc1, heavyFunc2, self.postmessage);
self.onmessage = function(e) {
    if (e.data === 'stop') msg = sequence.stop;
    else msg = sequence.run(e.data); //resets and restarts
};
我环顾四周,可以想到以下工具和模式:

setTimout(fcn,0)| setImmediate(fcn)shim:将各个步骤
setTimeout(fcn,0)
包装在主脚本和辅助程序的序列中,以在序列结束之前处理新事件

killFlag = false;
window.addEventListener('keypress', function() {killFlag = true});

//this exampe works only with setTimeout, fails with setImmediate lib
var interruptibleSequence = function(tasks) {
  var iterate = function() {
    if (killFlag || !tasks.length) return;
    tasks.shift()();
    if (tasks.length) window.setTimeout(iterate,0);
  };
  iterate();
};
此示例使用setTimeout,但使用setImmediate失败,其中按键事件总是最后出现

去盎司:这是一个典型的答案,似乎不适用于我的情况。延迟和批处理用户输入将部分降低处理强度,但以较长的处理时间为代价

承诺:我已经在使用工作结果承诺,并且可以在步骤之间引入额外的承诺,以中断序列并处理新事件。我尝试过(但失败)使用标志检查或
Promise.race

带杀旗

带着承诺。种族

问题
建议使用什么模式在事件上终止序列?

简而言之:调用堆栈>>承诺>>消息队列(事件和设置超时)

事实证明,这个问题表述得很糟糕,而且对于特定的用例来说太具体了。通常,对于立即返回的同步函数,将它们包装成承诺序列确实会将控制权移交给下一个函数,但仍然优先于消息队列中的事件,即使是在创建承诺之前触发的事件。公认的答案并不总是有效的

在下面的代码段中,事件、承诺、同步调用最终以Sync、承诺、事件顺序执行。(需要本地承诺)

因此,让事件中断繁重计算的唯一方法是使用setTimeout启动繁重的同步功能

//准备
函数日志(m){document.getElementsByTagName('pre')[0].innerHTML+=m+'
'} 功能同步延迟(毫秒){
对于(var tgt=Date.now()+ms;Date.now()解析或拒绝基于布尔值或标志的承诺(中断)?如果可能,可以发布
js
?是的。我可以用一个片段将这个案例添加到问题中。你的意思是:
step2=step1。然后(函数(结果){If(killFlag){return else}else{return fcn2(result)})
?优点和缺点可能与Promise.race.related相同:
killFlag = false;
window.addEventListener('keypress', function() {killFlag = true});

//does not work. promises get priority and event is only triggered last
var interruptibleSequence = function(tasks) {
  var seq = Promise.resolve();
    tasks.forEach(function(task){
      seq = seq.then(function() {
        if (killFlag) return;
        else task();
    });
  });
};
var killTrigger;
var killPromise = new Promise(function(res,rej){killTrigger = rej});
window.addEventListener('keypress', killTrigger());

//does not work. promises get priority and event is only triggered last
var raceToFailure = function(tasks) { 
  var seq = Promise.resolve();
  tasks.forEach(function(task){
    seq = Promise.race([seq.then(task),killPromise]);
  });
};