让前端飞Web前端之路前端面试题

对于promise的常见面试题总结分析

2019-06-27  本文已影响15人  Vicky丶Amor

1、了解 Promise 吗?

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

Promise解决的痛点:

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

4、Promise 如何使用?

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

Promise.resolve(value)

类方法,该方法返回一个以 value 值解析后的 Promise 对象
如果这个值是个 thenable(即带有 then 方法),返回的 Promise 对象会“跟随”这个 thenable 的对象,采用它的最终状态(指 resolved/rejected/pending/settled
如果传入的 value 本身就是 Promise 对象,则该对象作为 Promise.resolve 方法的返回值返回
其他情况以该值为成功状态返回一个 Promise 对象

Promise.reject

类方法,且与 resolve 唯一的不同是,返回的 promise 对象的状态为 rejected

Promise.prototype.then

实例方法,为 Promise 注册回调函数,函数形式:fn(vlaue){}value 是上一个任务的返回结果,then 中的函数一定要 return 一个结果或者一个新的 Promise 对象,才可以让之后的then 回调接收

Promise.prototype.catch

实例方法,捕获异常,函数形式:fn(err){}, err 是 catch 注册 之前的回调抛出的异常信息

Promise.race

类方法,多个 Promise 任务同时执行,返回最先执行结束的 Promise 任务的结果,不管这个 Promise 结果是成功还是失败

Promise.all

类方法,多个 Promise 任务同时执行
如果全部成功执行,则以数组的方式返回所有 Promise 任务的执行结果。 如果有一个 Promise 任务 rejected,则只返回 rejected 任务的结果

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

事件循环

promise的事件循环

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

8、能不能手写一个 Promise 的 polyfill?

function Promise(fn){
        //  说明 Promise必须以构造函数形式被调用
        if(!(this instanceof  Promise))
            throw  new TypeError('Promises must be constructed via new');
        // 说明 Promise的唯一参数fn必须是函数类型
        if(typeof fn !== "function")
            throw new TypeError('not a function');
        // _state属性定义了Promise的状态
        // Promise有pending、fulfilled、rejected三种状态,分别对应_state值为0、1、2
        this._state = 0;
        // _handled属性的类型为Boolean,初始值为false,其代表Promise是否被处理
        this._handled = false;
        //  _value属性的类型为Promise或undefined,初始值为undefined
        this._value = undefined;
        // _deferreds属性的类型为Array,初始值为空数组,数组中存放的值为Function
        this._deferreds = [];
        // 将Promise的参数fn与代表当前对象的this作为参数,deResolve函数进行调用
        doResolve(fn,this);
    }

function doResolve(fn, self) {
        // done变量的作用就是为了防止resolve()和reject()被同时调用
        //  Promise的状态只能从pending->fulfilled或pending->rejected
        var done = false;
        try {
            //  fn的构造函数的参数,new Promise传入的回调函数  fn(resolve,reject);
            fn(
                    function(value) {
                        if (done) return;
                        // done变量为true则直接退出函数
                        done = true;
                        resolve(self, value);
                    },
                    function(reason) {
                        if (done) return;
                        done = true;
                        reject(self, reason);
                    }
            );
        } catch (ex) {
            // 调用Promsie构造函数如果抛出异常,则Promise就会变为rejected状态
            if (done) return;
            done = true;
            reject(self, ex);
        }
}
 const promiseStatusSymbol = Symbol("PromiseStatus");
    const promiseValueSymbol = Symbol("PromiseValue");
    // pending、fulfilled、rejected
    const status = {
        pending:"pending",
        fulfilled:"fulfilled",
        rejected:"rejected"
    };
    const transition = function(status){
    /*    var self = this;
        return function(value){
            this[promiseStatusSymbol] = status;
            this[promiseValueSymbol] = value;
        }*/

       return (value) => {
            this[promiseValueSymbol] = value;
            setStatus.call(this,status);
        }
    };

    // 对于状态的改变进行控制
    // 如果状态从 pending 到 fulfilled, 那么调用链式的下一个fulfilled函数
    // 如果状态从 pending 到 rejected, 那么调用链式的下一个rejected函数
    const setStatus = function(status){
       this[promiseStatusSymbol] = status;
       if(status === status.fulfilled){
           this.deps.resolver && this.deps.resolver();
       }else if( status === status.rejected){
           this.deps.rejector && this.deps.rejector();
       }
    };

    // 当开始异步操作的时候,还没有结果的时候,处于pending状态,然后再改变为成功或者是失败的状态
    const promise = function(resolver){
      if(typeof  resolver !== "function"){
          throw new TypeError("parameter 1 must be a function");
      }
        this[promiseStatusSymbol] = status.pending;
        this[promiseValueSymbol] = [];
        this.deps = [];
        resolver(
            //  返回函数resolve和reject
            //  这两个函数会分别对当期的Promise的状态和值进行修改,修改成功或者失败
            transition.call(this,status.fulfilled),
            transition.call(this.status.rejected)
        );
    };

    // promise的链式调用主要是一个对于依赖进行依次收集的过程,then方法是添加依赖,不是执行回调函数
    promise.prototype.then = function(fulfilled,rejected){
        const self = this;
        return promise(function(resolve,reject){
           const callback = function () {
               // 回调函数执行的返回值需要保存下来
               // 在链式调用的时候,参数应该传递给链式调用的下一个
               const resoleValue = fulfilled(self[promiseValueSymbol]);
              // resolve(resoleValue);
              // 返回值相当于是一个thenable对象,改变直接调用then方法,获取一个返回值
              if(resoleValue && typeof resoleValue.then === "function"){
                  // 内嵌promise,将得到的值绑定在promise的依赖中
                  resoleValue.then(function(data){
                      resolve(data);
                  },function(err){
                      reject(err);
                  });
              }else{
                  // then 方法链式调用的连接点
                  // 在初始化状态或者上一次promise的状态发生改变的时候,调用当前promise成功的方法
                  //  对当前promise的状态进行改变,以及进行调用链式的下一个promise的回调
                  resolve(resoleValue);
              }
           };
           const errCallback = function(){
               const rejectValue = rejected(self[promiseValueSymbol]);
               reject(rejectValue);
           };

           // 对于promise的状态处理
           // 如果上一个promise在执行then方法之前就已经完成了,那么下一个promise对应的回调应该立即执行
           // 如果当前的状态为pending,说明promise的异步操作还没有决议,
          //成功和失败的回调应该保存在之前的promise的依赖之中
            if(self[promiseStatusSymbol] === status.fulfilled){
               return callback();
           }else if(self[promiseStatusSymbol] === status.rejected){
               return errCallback();
           }else if(self[promiseStatusSymbol] === status.pending){
               self.deps.resolver = callback;
               self.deps.rejector = errCallback;
           }
        });
    };

9、 Promise的问题?解决办法?

promise的问题为:

解决办法

10、手写Promise与ajax的结合?

实例代码:

function promiseGet (url) {
  return new Promise((resolve, reject) => {
    let xhr = new XMLHttpRequest()
    xhr.open('GET', url, true)
    xhr.onreadystatechange = function () {
      if (this.readyState === 4) {
        if (this.status === 200) {
          resolve(this.responseText,this)
        } else {
          let resJson = {
            code: this.status,
            response: this.response
          }
          reject(resJson, this)
        }
      }
    }
  })

作者:旧城tk
链接:https://juejin.im/post/5d10dfeb6fb9a07ecc44921c

求点赞,求关注~


上一篇下一篇

猜你喜欢

热点阅读