• es6面试题--Promise相关


    1、

    const promise = new Promise((resolve, reject) => {
        console.log(1);
        resolve();
        console.log(2);
    });
    promise.then(() => {
        console.log(3);
    });
    console.log(4);

    输出结果为:1,2,4,3。

      解题思路:then方法是异步执行的。

    2、

    const promise = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('success')
        reject('error')
      }, 1000)
    })
    promise.then((res)=>{
      console.log(res)
    },(err)=>{
      console.log(err)
    })

    输出结果:success

      解题思路:Promise状态一旦改变,无法在发生变更。

    3、

    Promise.resolve(1)
      .then(2)
      .then(Promise.resolve(3))
      .then(console.log)

    输出结果:1

      解题思路:Promise的then方法的参数期望是函数,传入非函数则会发生值穿透。

    4、

    setTimeout(()=>{
      console.log('setTimeout')
    })
    let p1 = new Promise((resolve)=>{
      console.log('Promise1')
      resolve('Promise2')
    })
    p1.then((res)=>{
      console.log(res)
    })
    console.log(1)

    输出结果:

        Promise1
        1
        Promise2
        setTimeout

      解题思路:这个牵扯到js的执行队列问题,整个script代码,放在了macrotask queue中,执行到setTimeout时会新建一个macrotask queue。但是,promise.then放到了另一个任务队列microtask queue中。script的执行引擎会取1个macrotask queue中的task,执行之。然后把所有microtask queue顺序执行完,再取setTimeout所在的macrotask queue按顺序开始执行。(具体参考https://www.zhihu.com/question/36972010

    5、

    Promise.resolve(1)
        .then((res) => {
            console.log(res);
            return 2;
        })
        .catch((err) => {
            return 3;
        })
        .then((res) => {
            console.log(res);
        });

    输出结果:1  2

      解题思路:Promise首先resolve(1),接着就会执行then函数,因此会输出1,然后在函数中返回2。因为是resolve函数,因此后面的catch函数不会执行,而是直接执行第二个then函数,因此会输出2。

    6、

    const promise = new Promise((resolve, reject) => {
    setTimeout(() => {
    console.log('开始');
    resolve('success');
    }, 5000);
    });
     
    const start = Date.now();
    promise.then((res) => {
    console.log(res, Date.now() - start);
    });
     
    promise.then((res) => {
    console.log(res, Date.now() - start);
    });

    输出结果:

        开始

        success 5002

        success 5002

      解题思路:promise 的.then或者.catch可以被调用多次,但这里 Promise 构造函数只执行一次。或者说 promise 内部状态一经改变,并且有了一个值,那么后续每次调用.then 或者.catch都会直接拿到该值。

    7、

    let p1 = new Promise((resolve,reject)=>{
      let num = 6
      if(num<5){
        console.log('resolve1')
        resolve(num)
      }else{
        console.log('reject1')
        reject(num)
      }
    })
    p1.then((res)=>{
      console.log('resolve2')
      console.log(res)
    },(rej)=>{
      console.log('reject2')
      let p2 = new Promise((resolve,reject)=>{
        if(rej*2>10){
          console.log('resolve3')
          resolve(rej*2)
        }else{
          console.log('reject3')
          reject(rej*2)
        }
      })
      return p2
    }).then((res)=>{
      console.log('resolve4')
      console.log(res)
    },(rej)=>{
      console.log('reject4')
      console.log(rej)
    })

    输出结果:

        reject1
        reject2
        resolve3
        resolve4
        12

      解题思路:我们上面说了Promise的先进之处在于可以在then方法中继续写Promise对象并返回。

    8、实现一个简单的promise

    function Promise(fn){
      var status = 'pending'
      function successNotify(){
          status = 'fulfilled'//状态变为fulfilled
          toDoThen.apply(undefined, arguments)//执行回调
      }
      function failNotify(){
          status = 'rejected'//状态变为rejected
          toDoThen.apply(undefined, arguments)//执行回调
      }
      function toDoThen(){
          setTimeout(()=>{ // 保证回调是异步执行的
              if(status === 'fulfilled'){
                  for(let i =0; i< successArray.length;i ++)    {
                      successArray[i].apply(undefined, arguments)//执行then里面的回掉函数
                  }
              }else if(status === 'rejected'){
                  for(let i =0; i< failArray.length;i ++)    {
                      failArray[i].apply(undefined, arguments)//执行then里面的回掉函数
                  }
              }
          })
      }
      var successArray = []
      var failArray = []
      fn.call(undefined, successNotify, failNotify)
      return {
          then: function(successFn, failFn){
              successArray.push(successFn)
              failArray.push(failFn)
              return undefined // 此处应该返回一个Promise
          }
      }
    }

    解题思路:Promise中的resolve和reject用于改变Promise的状态和传参,then中的参数必须是作为回调执行的函数。因此,当Promise改变状态之后会调用回调函数,根据状态的不同选择需要执行的回调函数。

    转自:https://www.cnblogs.com/lunlunshiwo/archive/2018/04/16/8852984.html

  • 相关阅读:
    Chrome 使用 Evernote 插件
    【MySQL】ON DUPLICATE KEY UPDATE
    【MySQL】Illegal mix of collations (utf8mb4_general_ci,IMPLICIT) and ...
    libevent API
    LLServer--》对LevelDB的应用
    Linux信号signal处理机制
    守护进程
    使用 libevent 和 libev 提高网络应用性能(IBM)
    Libev和LibEvent
    利用TokyoTyrant构建兼容Memcached协议、支持故障转移、高并发的分布式Key-value持久存储系统(转)
  • 原文地址:https://www.cnblogs.com/xuepei/p/8855913.html
走看看 - 开发者的网上家园