首页新闻找找看学习计划

js中如何从外部中断某函数的执行??

0
悬赏园豆:200 [已解决问题] 解决于 2017-10-27 11:25

众所周知,js是单线程的,没法保持多个函数同时运行。一直没有找到外部中断某函数运行的方法。

应用场景是:我有一个js 下棋的AI程序,AI在思考某一步棋的时间可能要花很长时间去计算(可能超过一两分钟),在这个计算过程中,整个页面都处于一个假死状态,用户点结束或退出按钮都不会有反应,造成很不好的用户体验。想找一个方法,AI在计算时,点个按钮就强行中止它的计算。一直没找到好的方法解决这个问题。

飞不动的主页 飞不动 | 初学一级 | 园豆:104
提问于:2017-10-22 10:37
< >
分享
最佳答案
1

个人认为可以将演算部分交给后台解决,前台用Ajax调用,并设置超时时间。

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
    if (xhr.readyState == 4) {
        alert("ready state = 4");
    }
};

xhr.open("POST", "http://www.example.com", true);
xhr.ontimeout = function () { alert("Timed out!!!"); }
xhr.send();

btn.click = function() {
    xhr.timeout = 1000;
}

不过没有验证过。

收获园豆:150
逐影 | 小虾三级 |园豆:1182 | 2017-10-22 11:37

这种方式是可以中断,因为ajax可以异步执行。但是我的AI计算不能放到后台进行,因为计算量太大,如果多用户并发,后台服务器根本计算不过来。

飞不动 | 园豆:104 (初学一级) | 2017-10-22 12:07

@飞不动: 那可以考虑一下web worker,现代浏览器基本上都支持JS多线程了。

逐影 | 园豆:1182 (小虾三级) | 2017-10-22 12:21

@逐影: 非常感谢,用web worker初步试验比较成功。不知web worker现在兼容性如何,手机上主流浏览器是否支持?

飞不动 | 园豆:104 (初学一级) | 2017-10-22 23:15

@飞不动: 

 

FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)Firefox OS (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support(基础支持) 4.4 4[1] 3.5 1.0.1 10.0 11.5[1] 5.1[2]
Shared workers(共享worker) 未实现 4[1] 8 1.0.1 未实现 未实现 未实现
Passing data using structured cloning(使用结构化克隆传递数据) 未实现 4 8 1.0.1 未实现 未实现 未实现
Passing data using transferable objects(使用可转让对象传递数据) 未实现 未实现 18 1.0.1 未实现 未实现 未实现

逐影 | 园豆:1182 (小虾三级) | 2017-10-22 23:52
其他回答(1)
0

这个场景,使用ServiceWorker来进行高负载运行,然后再每次循环的是时候,判断下终止变量。通过外部发消息给ServiceWorker,来设置终止变量。

// 大致思路如下
var isStop = false;
function run(){
  if(!isStop){
    while(){} // 高负载任务,注意,把长期的任务分解下。
  }
  setTimeout(()=>fun()); // 通过延迟执行,才能让引擎接收外部消息
}
run();
收获园豆:50
幻天芒 | 园豆:36522 (高人七级) | 2017-10-22 15:54

刚了解了一下ServiceWorker,该功能似乎支持的浏览器不多,并且还是试用阶段,不太敢用到产品中去。

web worker倒是一个比较好的思路,以前对这方面了解得很少。初步了解它不能跟dom交互,估计要用它我的程序也要做比较大的改动,我准备做一些偿试。

两位的回答对我都很有帮助,开阔了我的思路。非常感谢!

支持(0) 反对(0) 飞不动 | 园豆:104 (初学一级) | 2017-10-22 20:30

@飞不动: 抱歉,有些误导。ServiceWorker是基于WebWorker,针对缓存功能的。多余多线程,还是应该使用WebWorker。至于和dom交互,需要通过消息通知,让主线程进行dom操作。

支持(0) 反对(0) 幻天芒 | 园豆:36522 (高人七级) | 2017-10-23 12:47
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册