js 宏任务和微任务

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

 

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

 

 

3.相关文章

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

js 宏任务和微任务

彻底理解setTimeout()

 

转载于:https://www.cnblogs.com/justSmile2/p/11185045.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值