• js 宏任务和微任务 promise


    1.概念:宏任务(macrotask )和微任务(microtask ) 表示异步任务的两种分类。常见宏任务:I/O 、setTimeout、setInterval;微任务:Promise.then catch finally、process.nextTick

    在挂起任务时,JS 引擎会将 所有任务 按照类别分到这两个队列中,

    首先在 macrotask 的队列(这个队列也被叫做 task queue)中取出第一个任务,执行完毕后取出 microtask 队列中的所有任务顺序执行;

    之后再取 macrotask 任务,周而复始,直至两个队列的任务都取完。

    2.代码

    2.1 基本执行顺序 

    // 主线程(外层宏) -  微  -  宏
    //  1  1.1  -  2  -  3     
    setTimeout(() => {
        console.log('3')
    }, 0)
    console.log('1');
    
    new Promise((resolve) => {
        console.log('1.1');
        resolve()
    }).then(() => {
        console.log('2');
    }).then(()=>{
        console.log('2.1')
    })
    View Code
    setTimeout(_ => console.log(4))
    
    new Promise(resolve => {
      resolve()
      console.log(1)
    }).then(_ => {
      console.log(3)
    })
    
    console.log(2)
    View Code
            setTimeout(_ => console.log(4))
    
            new Promise(resolve => {
                resolve()
                console.log(1)
            }).then(_ => {
                console.log(3)
            })
    
            console.log(2)
    View Code
            setTimeout(() => {
                console.log("宏2");
            }, 1000);
    
            setTimeout(() => {
                console.log("宏3");
            }, 100);
    
            console.log("同步");
    
            new Promise((resolve, reject) => {
                    setTimeout(() => {
                        console.log("宏1");
                    }, 0)
                    console.log("立即");
                    resolve();
                    // reject()
                })
                .then(() => {
                    console.log("微0");
                })
                .then(() => {
                    console.log("微0");
                })
                .catch(() => {
                    console.log("err");
                })
    
            //  同步  立即   微0  微0   宏1  宏3   宏2
    View Code

    2.2 深度解析案例 :单组依次执行

    console.log('1');
    setTimeout(function() {
        console.log('3');
        new Promise(function(resolve) {
            console.log('3.1');
            resolve();
        }).then(function() {
            console.log('4')
        })
    })
    
    new Promise(function(resolve) {
        console.log('1.1');
        resolve();
    }).then(function() {
        console.log('2')
    })
    
    setTimeout(function() {
        console.log('5');
        new Promise(function(resolve) {
            console.log('5.1');
            resolve();
        }).then(function() {
            console.log('6')
        })
    })
    View Code

     2.3 promise ES5实现

    function MyPromise(fn) {
        var value = null,
            callbacks = [];
        this.then = function (onFulfilled) {
            callbacks.push(onFulfilled);
            return this;
        };
        function resolve(value) {
            setTimeout(function () {
                callbacks.forEach(function (callback) {
                    callback(value);
                });
            },0)
        }
        fn(resolve);
    }
    
    
    function test() {
        return new MyPromise(function(resolve) {
            console.log('1');
            resolve();
        })
    }
    
    test().then(function(resolve) {
        console.log('2');
    }).then(function(resolve) {
        console.log('3');
    });
    View Code

     更全的方式

    /**
     * Promise类实现原理
     * 构造函数传入一个function,有两个参数,resolve:成功回调; reject:失败回调
     * state: 状态存储 [PENDING-进行中 RESOLVED-成功 REJECTED-失败]
     * doneList: 成功处理函数列表
     * failList: 失败处理函数列表
     * done: 注册成功处理函数
     * fail: 注册失败处理函数
     * then: 同时注册成功和失败处理函数
     * always: 一个处理函数注册到成功和失败
     * resolve: 更新state为:RESOLVED,并且执行成功处理队列
     * reject: 更新state为:REJECTED,并且执行失败处理队列
    **/
    
    class PromiseNew {
      constructor(fn) {
        this.state = 'PENDING';
        this.doneList = [];
        this.failList = [];
        fn(this.resolve.bind(this), this.reject.bind(this));
      }
    
      // 注册成功处理函数
      done(handle) {
        if (typeof handle === 'function') {
          this.doneList.push(handle);
        } else {
          throw new Error('缺少回调函数');
        }
        return this;
      }
    
      // 注册失败处理函数
      fail(handle) {
        if (typeof handle === 'function') {
          this.failList.push(handle);
        } else {
          throw new Error('缺少回调函数');
        }
        return this;
      }
    
      // 同时注册成功和失败处理函数
      then(success, fail) {
        this.done(success || function () { }).fail(fail || function () { });
        return this;
      }
    
      // 一个处理函数注册到成功和失败
      always(handle) {
        this.done(handle || function () { }).fail(handle || function () { });
        return this;
      }
    
      // 更新state为:RESOLVED,并且执行成功处理队列
      resolve() {
        this.state = 'RESOLVED';
        let args = Array.prototype.slice.call(arguments);
        setTimeout(function () {
          this.doneList.forEach((item, key, arr) => {
            item.apply(null, args);
            arr.shift();
          });
        }.bind(this), 200);
      }
    
      // 更新state为:REJECTED,并且执行失败处理队列
      reject() {
        this.state = 'REJECTED';
        let args = Array.prototype.slice.call(arguments);
        setTimeout(function () {
          this.failList.forEach((item, key, arr) => {
            item.apply(null, args);
            arr.shift();
          });
        }.bind(this), 200);
      }
    }
    
    // 下面一波骚操作
    new PromiseNew((resolve, reject) => {
      resolve('hello world');
      // reject('you are err');
    }).done((res) => {
      console.log(res);
    }).fail((res) => {
      console.log(res);
    })
    View Code

     2.4 promise 常见用法

    链式调用:

    Promise的精髓是“状态”,用维护状态、传递状态的方式来使得回调函数能够及时调用,它比传递callback函数要简单、灵活的多

    超时:

    用race给某个异步请求设置超时时间,并且在超时后执行相应的操作

    3.相关文章

    js 宏任务和微任务介绍及实例讲解

    js 宏任务和微任务

    彻底理解setTimeout()

     大白话讲解Promise

  • 相关阅读:
    C连载20-转换说明中的异常
    Android连载30-SharedPreference存储
    搭建一个开源项目12-Kubernetes集群部署(下)以及elasticsearch部署
    JavaScript连载29-元素类型获取、节点CD
    从零开始学VUE之模板语法(计算属性)
    从零开始学VUE之模板语法(绑定属性)
    从零开始学VUE之模板语法(插值操作)
    从零开始学VUE之Vue的生命周期
    从零开始学VUE之Vue创建时可以传入的Option属性
    从零开始学VUE之Vuejs初体验(DEMO)
  • 原文地址:https://www.cnblogs.com/justSmile2/p/11185045.html
Copyright © 2020-2023  润新知