Promise与事件循环

960 阅读3分钟

js异步

  • Promise

    1、了解 Promise 吗?

    2、Promise 解决的痛点是什么?

    3、Promise 解决的痛点还有其他方法可以解决吗?如果有,请列举。

    4、Promise 如何使用?

    5、Promise 常用的方法有哪些?它们的作用是什么?

    6、Promise 在事件循环中的执行过程是怎样的?

    7、Promise 的业界实现都有哪些?

    回答1:Promise 是异步编程的一种解决方案,比传统的异步解决方案【回调函数】和【事件】更合理、更强大。现已被 ES6 纳入进规范中。一个 Promise 对象有三个状态,并且状态一旦改变,便不能再被更改为其他状态。

    • pending,异步任务正在进行。
    • resolved (也可以叫fulfilled),异步任务执行成功。
    • rejected,异步任务执行失败。

    回答2:promise解决了过多异步请求嵌套时,产生的回调地狱问题;当需求越来越变态的时候,上一个异步请求的结果需要作为下一个异步请求的条件且这样的情况越来越多时,这就是回调地狱。

    回答7:业界其他解决回调地狱痛点的实现:著名的 Q 和 bluebird,bluebird 甚至号称运行最快的类库。

    回答4:初始化一个Promise对象,可以通过两种方式创建, 这两种方式都会返回一个 Promise 对象。

    · new Promise(fn)
    · Promise.reslove(fn)
    
    function fn(reslove,reject){
        setTimeout(function(){
            reslove('返回一个值')
        },3000)
    }
    

    然后调用上一步返回的Promise对象的then方法,注册回调函数。

    then 中的回调函数可以有一个参数,也可以不带参数。如果 then 中的回调函数依赖上一步的返回结果,那么要带上参数
    new Promise(fn)
        .then(fn1(value){
            //处理value
        })
    
    

    最后注册 catch 异常处理函数,处理前面回调中可能抛出的异常。

    回答5: 常用api

    • Promise.reslove(fn),返回一个Promise对象,传入值会影响返回值
    • Promise.reject
    • Promise.prototype.then
    • Promise.prototype.catch
    • Promise.race
    • Promise.all

    Promise升级:ES6 出现了 generator 以及 async/await 语法,使异步处理更加接近同步代码写法,可读性更好,同时异常捕获和同步代码的书写趋于一致

    (async ()=>{
        let 蔬菜 = await 买菜();
        let 饭菜 = await 做饭(蔬菜);
        let 送饭结果 = await 送饭(饭菜);
        let 通知结果 = await 通知我(送饭结果);
    })();
    	async/await也是基于 Promise 实现的,所以,我们仍然有必要深入理解 Promise 的用法
    
  • EventLoop

    • 宏任务与微任务

      这两个任务分别维护一个队列,同步执行的任务都在宏任务上执行。

      宏任务主要有:script(整体代码)、setTimeout、setInterval、I/O、UI交互事件、postMessage、MessageChannel、setImmediate(Node.js 环境)。

      微任务主要有:Promise.then()、MutationObserver、 process.nextTick(Node.js 环境)。

      具体执行步骤

      1. 从宏任务队列头部取出一个任务(一开始执行js代码的操作就是第一个宏任务,并且第一个宏任务执行过程中,会将所有的宏任务按顺序加入队列中)
      2. 宏任务执行过程中,遇到微任务就将其加入到微任务队列中
      3. 宏任务执行完毕后,检查微任务的队列中是否存在任务,若存在,则挨个儿出去执行,直到执行完毕
      4. GUI渲染,requestAnimationFrame()在GUI渲染前、微服务之后执行
      5. 微任务执行完毕后,回到步骤1
    • async-await:Promise和generator语法糖

    • requestAnimationFrame:也属于异步执行的方法,但该方法既不属于宏任务,也不属于微任务