
方案1:针对支持html5 webworker的现代浏览器方案:。
代码1你的大量计算,放到一个js文件中。如下:
//jobjsonmessage =function (evt){
//do massive job在这里你进行大量耗时的计算过程。
postMessage( data );//将计算结果的数据发送会主线程
}
你的页面代码:
<!DOCTYPE HTML><html>
<head>
<meta ;
方案2:对于不支持WebWorker线程的浏览器。
可以考虑分批处理。即是说创造一个间隔定时器setInterval。
每隔一小段时间,处理大量数据中的一部分。
这样就可以避免大量计算导致浏览器卡死。
大致代码如下(这里是简单的例子。具体情况具体分析。):
假设我们要计算1000万个数据的和。
var jobData = [];//假设是一个数组。里面有1000万个数据。function sliceJob(){
var num = (jobDatalength / 100) + 1;//把任务数据划分为100份。
var portion = 100000;//每份有10万个数字。
var addition = 0;//这里用来保存最后的结果。一开始是0;
var intv = setInterval(function(){
if(num--){
//然后每一份结果。
additoin += every;
} else {
计算最后一份,然后输出结果。
alert('最终结果是:', addition);
windowclearInterval(intv);
}
}, 50);
}
此外。jQuery的deferred对象无法实现你的要求。
因为deferred对象的目的是为了串行处理异步过程。
但是异步过程在执行的过程中,如果耗时过长,仍然会阻塞浏览器线程,导致浏览器不可 *** 作(卡死)。
唯一的一个例外是$ajax。$ajax方法也会返回一个Deferred对象。但是由于该异步过程是用的XML>
看了你的问题,才百度学习的Promise,不知道是不是你要的效果。
function async1(){return new Promise(function(resolve, reject) {
setTimeout(function() {//setTimeout模拟异步
consolelog('async1 is done');
resolve('async1 value');
}, 6000);
});
}
function async2(){
return new Promise(function(resolve, reject) {
setTimeout(function() {//setTimeout模拟异步
consolelog('async2 is done');
resolve('async2 value');
}, 3000);
});
}
function async3(){//async3不需要then,所以没写return new Promise
setTimeout(function() {
consolelog('async3 is done');
}, 1000);
}
let p;
for(let i=0;i<4;i++){
p=async1()then(async2);
}
pthen(async3);
Event Loop即事件循环,是解决javaScript单线程运行阻塞的一种机制。 主要是为了协调单线程下,事件、用户交互、脚本、UI 渲染和网络处理等行为,防止主线程的不阻塞。
因为JavaScript 是单线程,也就是说, 所有任务需要排队,前一个任务结束,才会执行后一个任务。
但是IO设备(输入、出设备)可能会因为网络等因数导致速度很慢(比如Ajax)继而CPU没有充分利用,所以设计者将IO设备的任务挂起,先执行后面的任务,等到IO设备返回了结果,再回过头,把挂起的任务继续执行下去。于是,就把所有任务分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。
只有前一个任务执行完毕,才能执行后一个任务;直接在主线程上排队执行且最先执行,形成一个执行栈
不进入主线程、而是进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",执行一个宏任务, 执行过程中如果遇到微任务,就将它添加到微任务的任务队列中 宏任务执行完毕后,再依次执行执行当前微任务队列中的所有微任务,当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染 渲染完毕后,JS线程继续接管,开始下一个宏任务(从事件队列中获取)
(4)主线程不断重复上面的第三步。
"任务队列"是一个先进先出的数据结构,也是一个事件的队列(也可以理解成消息的队列),IO设备完成一项任务,就在"任务队列"中添加一个事件,表示相关的异步任务可以进入"执行栈"了。主线程读取"任务队列",就是读取里面有哪些事件。
"任务队列"中的事件,除了IO设备的事件以外,还包括一些用户产生的事件(比如鼠标点击、页面滚动等等)。只要指定过回调函数,这些事件发生时就会进入"任务队列",等待主线程读取。
所谓"回调函数"(callback),就是那些会被主线程挂起来的代码。异步任务必须指定回调函数,当主线程开始执行异步任务,就是执行对应的回调函数。
例子1
例子2:
例子3:
nodejs事件循环和浏览器的事件循环不一样的。 浏览器的Event loop是在HTML5中定义的规范,而node中则由libuv库实现
我们先来看一个例子
在JS方法里面设置一个for循环,输出每次循环的值,如下图
我们可以根据闭包的知识来更改一下for循环中的逻辑,利用闭包将i的值传递给a
这次在运行程序我们就可以看到输出内容是0开始输出了
结果如下图
JS中如果for循环中有异步方法,就需要用闭包的方式保留当前循环变量值
以上就是关于js 执行一个耗时 *** 作时,比如一个大的遍历,如何才能真正实现异步,让浏览器界面不会假死。全部的内容,包括:js 执行一个耗时 *** 作时,比如一个大的遍历,如何才能真正实现异步,让浏览器界面不会假死。、js 方法中存在$.post()异步请求、JS 怎么让整体的for同步执行而for中的异步函数异步执行等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)