关于异步

108 阅读2分钟

宏任务,微任务->requestAnimationFrame->render/layout->requestIdleCallback

requestAnimationFrame 是浏览器用于定时循环的一个接口,类似于setTimeout,主要用途是对网页进行重绘,(是浏览器内置).这样能够有一个统一的刷新机制,从而节省系统 资源 ,提高系统 性能。执行时机是浏览器在下次重绘之前调用指定的回调函数进行 更新动画。 该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前扫行

    (function animloop() {
        render();
        window.requestAnimationFrame(animloop);
    })()

它有返回值,可以中止循环

 var rafId=null
(function animloop(time) {
        render();  对于不同的业务,这里的执行时机可以具体定义
        rafId = requestAnimationFrame(animloop);
        //如果left等于50 停止动画
        if(left == 50){
            cancelAnimationFrame(rafId)
        }
 })();

requestIdleCallback【不太重要的任务,可以延迟的】 这个api的出现是为了提高浏览器的性能,用空余时间来处理延迟,不让用户觉得卡顿。

window.requestIdleCallback =
  window.requestIdleCallback ||
  function (handler) {
    let startTime = Date.now();
    return setTimeout(function () {
      handler({
        didTimeout: false,
        timeRemaining: function () {
          return Math.max(0, 50.0 - (Date.now() - startTime));
        },
      });
    }, 1);
  };
  requestIdleCallback(callback)
  callback:一个在事件循环空闲时即将被调用的函数的引用。函数会接收到一个名为 [`IdleDeadline`] 的参数,这个参数可以获取当前空闲时间以及回调是否在超时时间前已经执行的状态
  
  
var tasksNum = 10000

requestIdleCallback(unImportWork)

function unImportWork(deadline) {
  while (deadline.timeRemaining() && tasksNum > 0) {//有余下的时间
    console.log(`执行了${10000 - tasksNum + 1}个任务`)
    tasksNum--
  }

  if (tasksNum > 0) { // 在未来的帧中继续执行
    requestIdleCallback(unImportWork)
  }
}

一个简单的Promise实现

  1. Promise是一个构造函数
  2. Promise的入参是一个函数,这个函数的参数是两个函数(resolve,reject)
  3. Promise返回一个对象,这个对象包含一个then函数。这个then函数,接受两个入参,这两个入参也是函数
  4. Promise的state
  • pending
  1. 这是初始状态,可以改变
  2. 在resolve,reject调用之前,都处于这个状态
  3. 可以通过调用resolve,reject的方法,让这个promise的状态变为fulfiled或rejected
  • fulfilled
  1. 不可变状态
  2. 在resolve调用之后,变成这个状态,有一个value
  • rejected
  1. 不可变状态
  2. 在reject调用之后,变成这个状态,有一个value then函数
  3. 参数:onFulfilled,onRejected必须是函数类型,如果不是,应该被忽略
  4. onFullfilled和onRejected的特性
  • 在promise变成fulfilled/reject状态的时候,应该调用onFullfilled/onRejected
  • 在promise变成fulfilled/reject状态之前,不应该被调用
  • 只能调用一次
 function NPromsie(excute){
     this.status='pending'
     this.value=null
     this.reason=null
     const resolve=(value)=>{
        if(this.status=='pending'){
          this.status='fulfilled'
          this.value=value
        }
     }
     const reject=(value)=>{
        if(this.status=='pending'){
          this.status='rejected'
          this.reason=value
        }
     }
     excute(resolve,reject)
    }

    NPromsie.prototype.then=function(onFulfilled,onRejected){
        onFulfilled=typeof onFulfilled=='function'?onFulfilled:value=>value;
        onRejected=typeof onRejected=='function'?onRejected:()=>{throw Error('error')};
        if(this.status=='fulfilled') onFulfilled(this.value)
        if(this.status=='rejected') onRejected(this.reason)
    }

    let a= function(){
        return new NPromsie((resolve,reject)=>{
        resolve(12)
    })
}

    a().then(re=>{
    console.log(re)
    })  //调用a()后。返回创建的这个对象 这个对象的__proto__== NPromsie.prototype