Javascript运行机制

1.同步与异步

同步:按顺序,代码不中断的执行,常见的:console.log
异步:先执行一部,拿到结果,再执行后续的代码或者回调函数。
1.计时器(setTimeout,setInterval)
2.ajax
3.读取文件

执行顺序:先执行同步代码,再执行异步代码。

console.log(1);
for (let index = 0; index < 1000; index++) {
   console.log(index);
}
 setTimeout(()=>console.log(2),0);
 setTimeout(()=>console.log(3),0);
 setTimeout(()=>console.log(4),0);
 console.log(5);
执行结果为 1,for循环,5,2,3,4,不管同步带耗时多长,
都是先执行同步代码,因为js是单线程,所以会堵塞,等它执行完,
再执行另一个任务。所以得出一个结论,定时器任务可能是不准时的。

2.process.nextTick

什么时候执行:同步代码执行完,异步代码执行前,示例如下
 process.nextTick(()=>{
     console.log(1);
 })
 console.log(2);
 setTimeout(() => {
     console.log(3);
 }, 0);
 console.log(4);
执行结果为:
2
4
1
3

3.setImmediate

什么时候执行:异步代码对应的任务队列中,执行完当前的任务,则调用,示例如下
setImmediate(()=>{
     console.log(1);
 })

 console.log(2);

 setTimeout(() => {
     console.log(3);
 }, 0);

 setTimeout(() => {
    console.log(4);
}, 1000);

setTimeout(() => {
  console.log(5);
}, 0);
setTimeout(() => {
  console.log(6);
}, 2000);
 console.log(7);
 
执行结果:
2
7
3
5
1
4
6
1.**注意定时器的时间,并不是到点就执行**,而是过多少时间放在任务队列里,
2.因此就可以解释为什么定时器不准时。
3.所以先是执行完同步代码,再过0秒,把定时为0的定时器放入,
4.此时任务队列有任务就会被事件循环给扫描到,就先执行,等当前任务执行完就
执行setImmediate,
5.再过1s,2s,相应的定时器也加入到任务队列中,被扫描到就执行

4.宏任务与微任务

1.异步任务可分为 宏任务与微任务
2.宏任务:计时器,ajax,读取文件
3.微任务:promise.then
4.执行顺序:
* 1.同步程序
* 2.process.nextTick()
* 3.微任务
* 4.宏任务
* 5.setImmediate

示例代码:

 setImmediate(()=>{
     console.log(1);
 })

 console.log(2);

 setTimeout(() => {
     console.log(3);
 }, 0);

 setTimeout(() => {
    console.log(4);
}, 1000);

setTimeout(() => {
  console.log(5);
}, 0);

 new Promise((resolve)=>{
     console.log(6);
     resolve();
 }).then(()=>
 {console.log(7);
}
)

 process.nextTick(()=>{
     console.log(8);
 })
结果:
2
6
8
7
3
5
1
4

5.Promise和async和await

Promise:
先看代码:

let fn2=new Promise(()=>{
        console.log(1);
    })
fn2.then(()=>{
        console.log(2);
 })
	输出结果为1,没有2,因为Promise里面没有调用resolve方法,所以不会
执行then方法,而且resolve里面的数据是then里面函数的形参
let fn2=new Promise((resolve)=>{
        console.log(1);
        resolve(2);
    })
fn2.then((data)=>{
      console.log(data);
      console.log(3);
 })
执行结果为1,2,3

async:

先看一个方法加入async后的代码以及执行结果:
async function fun() {
    return 1;
}
let fn=fun();
console.log(fn);

结果:
Promise { 1 }
说明:async 返回值是个Promise对象

Promise后面可以接then,我们来看下运行效果

 async function fun() {
     return 1;
 }
 let fn=fun();
 fn.then((data)=>{
    console.log(data);
 });
 
 结果:
	1
所以可以看到这段代码等价于
let fn2=new Promise((resolve)=>{
       resolve(1);
    })
  fn2.then((data)=>{
      console.log(data);
 })
 可以看到到async本质就是Promise的语法糖

await

	async一般与await成对出现,await后面接的也是Promise对象,await 
只在异步函数里面才起作用,它会暂停代码在该行上,直到 promise 完成,
然后返回结果值(是获得resolve里的值)
function fn2(){
    return new Promise((resolve)=>{
        resolve(1);
    })
}   
function fn1(){
    return new Promise((resolve)=>{
        resolve(2);
    })
}
async function fun3(){
      let a=await fn1();
      console.log(3);
      let b=await fn2();
      //await这后面的代码可以理解为是在then里面的
      console.log(a,b);
      console.log(4);
  }
  fun3();

结果:
3
2 1
4
下面是道执行顺序的例题,大家可以试着去做一下
console.log(1);
async function async1(){
  await async2()
  console.log(2);
}
async function async2() {
  console.log(3);
}
async1();
setTimeout(() => {
  console.log(4);
}, 0);
new Promise(resolve=>{
  console.log(5);
  resolve();
}).then(()=>{
  console.log(6);
}).then(()=>{
  setTimeout(() => {
    console.log(7);
  }, 100);
})
console.log(8);

结果:
1
3
5
8
2
6
4
7

6.最后把JS运行机制的流程图发给大家参考

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值