zoukankan      html  css  js  c++  java
  • 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);
    

  • 相关阅读:
    gradle使用笔记
    MaxScale初探
    mariadb-10GTID复制及多源复制
    Shell中的循环语句实例
    Failed to load slave replication state from table mysql.gtid_slave_pos: 1146: Table 'mysql.gtid_slave_pos' doesn't exist
    学习MongoDB--(5-2):索引(查看索引的使用,管理索引)
    MongoDB索引管理
    mysql 5.5与5.6 timestamp 字段 DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP的区别
    MongoDB增加用户、删除用户、修改用户读写权限及只读权限(注:转载于http://www.2cto.com/database/201203/125025.html)
    MongoDB创建数据库
  • 原文地址:https://www.cnblogs.com/jianjie/p/13233865.html
Copyright © 2011-2022 走看看