498 同步、异步编程,宏任务、微任务

一、同步异步编程

(一)浏览器是多线程的

1. GUI渲染线程
2. HTTP网络请求线程(并发数6~7)
3. 事件监听、定时器监听\...

(二)JS代码的运行是单线程的

浏览器只分配一个GUI渲染线程去执行我们的JS代码

  1. 对于大部分JS代码来讲上面代码没有执行完,下面代码是不能执行的 “同步编程”
  2. 但是对于某些JS代码来讲(事件绑定、定时器、Promise/async/await、Ajax等),我们需要在上面代码没有处理的情况下,GUI渲染线程能够继续向下执行 “异步编程”


console.log(1);
console.time('AAA');
for (let i = 0; i < 99999999; i++) {
  if (i === 99999998) {
    console.log(2);
  }
}
console.timeEnd('AAA'); // => time/timeEnd可以记录一段程序执行的时间(时间受电脑性能和执行时候的环境转态影响) "事后统计法"   300MS~400MS
console.log(3); 


// 1 3 5 6 7 4 2
console.log(1);

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

console.log(3);

setTimeout(() => {
  console.log(4);
}, 0); // => 并不是立即执行, 需要等待浏览器的最小反应时间 5~6MS

console.log(5);

// console.time('A')
// 145ms左右
for (let i = 0; i < 99999999; i++) {
  if (i === 99999998) {
    console.log(6);
  }
}
// console.timeEnd('A')

console.log(7);


// 2 4 5 7 9    3 1 6 8 错误
// 2 4 5 7 9    6 3 8 1 
// 前面两个定时器都是循环结束前,放到任务队列中的;后面两个定时器都是循环结束后,放到任务队列中的。
// for循环结束后,前面2个定时器已经到了执行时间了,GUI渲染线程结束后,会先执行这两个定时器。
setTimeout(() => {
  console.log(1);
}, 20);

console.log(2);

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

console.log(4);

for (let i = 0; i < 90000000; i++) {
  // do soming  79MS
}

console.log(5);

setTimeout(() => {
  console.log(6);
}, 8);

console.log(7);

setTimeout(() => {
  console.log(8);
}, 15);

console.log(9);


for (var i = 0; i < 5; i++) {
  setTimeout(() => {
    console.log(i);
  }, 0);
}
// 第一次循环  向任务队列中插入一个定时器
// 第二次循环  向任务队列中插入一个定时器
// ...
// 第五次循环  向任务队列中插入一个定时器
// 循环结束 全局下的i=5  任务队列中有5个定时器  【GUI空闲】
//   定时器执行中遇到i 不是自己的,则找全局的,全局的i=5
//    => 5 * 5 

setTimeout(() => {
  console.log(1);
  while (1 === 1) { }
}, 10);

console.log(2);

for (let i = 0; i < 90000000; i++) {
  // do soming  79MS
}
// 循环结束  任务1已经到时间了
console.log(3);

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

console.log(5); 

async function async1() {
  console.log('async1 start');
  await async2();
  console.log('async1 end');
}
async function async2() {
  console.log('async2');
}
console.log('script start');
setTimeout(function () {
  console.log('setTimeout');
}, 0)
async1();
new Promise(function (resolve) {
  console.log('promise1');
  resolve();
}).then(function () {
  console.log('promise2');
});
console.log('script end');


// ------------------------

/*
 * 任务队列:
 *    微任务
 *       任务2:resolve(result)控制then存放的方法执行
 *    宏任务
 *       任务1:AJAX请求
 *
 * GUI空闲
 *    任务1数据请求回来,触发success回调函数,执行resolve(result) 【设置了一个微任务】
 * GUI空闲
 *    执行任务2
 */

new Promise(resolve => {
  $.ajax({
    url: 'xxx',
    success: result => {
      resolve(result);
    }
  });
}).then(result => {

}); 


function func1() {
  console.log('func1 start');
  return new Promise(resolve => {
    resolve('OK');
  });
}

function func2() {
  console.log('func2 start');
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('OK');
    }, 10);
  });
}

console.log(1);

setTimeout(async () => {
  console.log(2);
  await func1();
  console.log(3);
}, 20);

// 循环大约要进行80MS左右
for (let i = 0; i < 90000000; i++) { }

console.log(4);

func1().then(result => {
  console.log(5);
});

func2().then(result => {
  console.log(6);
});

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

console.log(8);

posted on 2020-07-04 09:56  冲啊!  阅读(195)  评论(0编辑  收藏  举报

导航