js 执行一个耗时 *** 作时,比如一个大的遍历,如何才能真正实现异步,让浏览器界面不会假死。

js 执行一个耗时 *** 作时,比如一个大的遍历,如何才能真正实现异步,让浏览器界面不会假死。,第1张

方案1:针对支持html5 webworker的现代浏览器方案:。

代码1你的大量计算,放到一个js文件中。如下:

//jobjs

onmessage =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中的异步函数异步执行等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9721300.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-01
下一篇2023-05-01

发表评论

登录后才能评论

评论列表(0条)

    保存