Javascript事件循环机制

在学明白事件循环机制之前,需要先明白几个概念。

js中的任务分为同步任务异步任务两种。

我们正常所写的按照顺序解释执行的代码都是同步任务,换句话说,代码当即就可以执行并不需要等待的都是同步任务。

而异步任务概念正好相反,需要等待一段时间执行的,或者说间隔一段时间执行的,像setTimeout,setInterval以及http请求等等,执行时和时间挂钩的任务,都是异步任务。

同步任务和异步任务最大的不同就是,同步任务是立即执行的,异步任务不是立即就执行的

异步任务又分为宏任务和微任务两种。

宏任务:异步任务当中执行优先级比较低的任务,setTimeout,steInterval,ajax,promise等都是宏任务。

微任务:部分同步任务执行时会附带微任务,微任务的执行发生在所有同步任务执行结束后,紧接着执行。要注意不是所有的同步任务都会附带微任务,只有一部分,目前为止只有两个同步任务会附带微任务,第一个是promise的then方法是微任务,第二个是node中process.nextTick()方法。

就像日常生活一样,你需要对你做的事情有安排。

js中对于任务的安排也在模拟现实生活。

我们来举一个例子,某天你结束了一天疲惫的工作下班回家,你进门先打开了热水器,因为你想吃完晚饭去洗澡。但是烧热水是个需要耗费时间的活,你不可能一直等待。于是乎你开始准备做饭,

假设今晚你吃老北京炸酱面,你正常的做法一定是先煮面条,趁着煮面条的时间去把炸酱和黄瓜丝胡萝卜丝准备好,等面条煮熟了把炸酱放上,大功告成。

好,请注意在以上的例子中,你做了三件事,烧热水,煮面,准备炸酱。

请你思考,上面三件事哪一件事不需要等待,直接就可以做,毫无疑问准备炸酱

哪一件事需要等待,但是一旦到了时间就必须立即执行,那当然是煮面条

那么烧热水洗澡这件事,虽然需要等待,但是并不一定要立即执行。

上面三件事分别对应js中的同步任务,微任务,宏任务。

所以我们也不难排列出优先级顺序:同步任务>微任务>宏任务

看下面这段代码的执行结果:

function app(){

    console.log(1);
    setTimeout(function(){
        console.log(4);
    },0)
    new Promise((resolve,reject)=>{
        //这里执行的是同步任务,
        console.log(2);
        resolve();
    }).then((value,reason)=>{
        //这里是微任务
        console.log(3);
    }  
        
    )
    console.log(5);

}
app();

毫无疑问执行结果应该是:

1

2

5

3

4

1,2,5都是同步任务,3是微任务,4是宏任务

js在执行任务的时候,会优先执行同步任务,把宏任务和微任务都分别放在一旁,宏任务会放在宏任务队列,微任务会放在微任务队列,当同步任务执行完成之后,会优先去微任务队列寻找需要执行的微任务,等待微任务执行完成之后才会去找宏任务队列,进一步执行宏任务。

以上就是事件循环机制的内容。

明白了这个道理之后,再来看一下下面这段代码的执行结果:


function app(){

    console.log(1);
    setTimeout(function(){
        console.log(2);
    },0)
    new Promise((resolve,reject)=>{
        //这里执行的是同步任务,
        console.log(3);
        resolve();
    }).then((value,reason)=>{
        //这里是微任务
        console.log(4);
    }  
        
    )
    console.log(5);
    new Promise((resolve,reject)=>{
        //这里执行的是同步任务,
        console.log(6);
        resolve();
    }).then((value,reason)=>{
        //这里是微任务
        console.log(7);
    } 
    )

}
app();

结果自然是:

1

3

5

6

4

7

2

我们研究事件循环机制有什么用呢?它能够帮助我们解决很多在开发过程中的问题。

来看一段代码:

var result=[];
$.ajax({

  type:'GET',
  url:url,
  success:data=>{
//假设我在这里请求回来一个数组data
  result=data;

}

})

console.log(result);

大家觉得执行结果是什么?

很显然是[ ],为什么?因为ajax是一个异步请求,是一个宏任务,当你打印result的时候它并没有请求成功,所以你没办法把请求回来的值赋给result,那么怎么办呢?最简单的办法就是加一个属性async:false,将ajax请求改为同步任务。

涉及到异步请求的例子其实都可以这样解决,再例如我们现在有这么一个需求,写一个函数,请求一段json,当我每次调用这个函数的时候请求回来一段json,return给我,要求用axios。

我们就可以这样做:

//引入axios,因为我是node环境,所以这样写
var axios=require("axios");
 function app(){
       return new Promise((resolve,reject)=>{
//请求外面套一层promise
        axios({
          method:'get',
          url:'http://localhost:9000/xzqservice/geomtry/330000'

           }).then(res=>{
            
            resolve(res.data);
           }
             
           )
       })
        
  }
  async function getData(){

    let data= await app();
    console.log(data); 
  }
  getData();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WebGIS小智

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值