【面试题】说一下promise的理解

简介: promise详解,方法的应用场景

一.什么是Promise?

ES6 异步编程的一种解决方案,比传统的方案(回调函数和事件)更加的合理和强大。大家都知道传统解决异步编程用的是回调函数套回调函数,简称回调地域。以前用JQuery的朋友应该是相当熟悉了。维护起来很难搞。

  • 回调地域

    var say = function (name, callback) {
         
      setTimeout(function () {
         
      console.log(name);
      callback();
    }, 1000);
    }
    // 回调地域
    say("张三", function () {
         
    say("李四", function () {
         
      say("王麻子", function () {
         
        console.log("班长");
      });
    });
    });
    
  • Promise

    var say = function (order) {
         
    return new Promise(function (resolve, reject) {
         
        setTimeout(function () {
         
        console.log(name);
        //在异步操作执行完后执行 resolve() 函数
        resolve();  
      }, 1000);
    });
    }
    say("张三").then(function () {
         
    //仍然返回一个 Promise 对象
    return say("李四");  
    }).then(function () {
         
    return say("王麻子");
    }).then(function () {
         
    console.log('班长');
    }).catch(function (err) {
         
      // 捕获异常
    console.log(err);
    })
    

二.Promise的优点

  1. 异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。
  2. 对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、resolved(已成功)和rejected(已失败)。
  3. 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为resolved和从pending变为rejected。
  4. promise内部发生错误,不会影响到外部程序的执行。
  5. 无法取消Promise。一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。第三,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

    三.用法

  • 创建promise实例

    const promise = new Promise(function(resolve, reject) {
         
    // ... some code
    
    if (/* 异步操作成功 */){
         
      resolve(value);
    } else {
         
      reject(error);
    }
    });
    
  • Promise.all 方法: (promises) => {}

    function PromiseAll(promises){
         
      return new Promise((resolve, reject)=>{
         
          if(!Array.isArray(promises)){
         
              throw new TypeError("promises must be an array")
          }
          let result = [] 
          let count = 0 
          promises.forEach((promise, index) => {
         
              promise.then((res)=>{
         
                  result[index] = res
                  count++
                  count === promises.length && resolve(result) 
              }, (err)=>{
         
                  reject(err)
              })
          })
      })
    }
    
  • Promise.race 方法: (promises) => {}
    promises: 包含 n 个 promise 的数组
    说明: 返回一个新的 promise, 第一个完成的 promise 的结果状态就是最终的结果状态。

    Promise.race = function(promiseArr) {
         
      return new Promise((resolve, reject) => {
         
          promiseArr.forEach(p => {
         
              Promise.resolve(p).then(val => {
         
                  resolve(val)
              }, err => {
         
                  rejecte(err)
              })
          })
      })
    }
    
  • Promise.finally():
    finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。
    Promise.finally()方法的使用场景:强制关闭弹框(个人理解),就是无论你成功还是失败总得做某件事的时候

    Promise.prototype.finally = function (cb) {
         
    return this.then(function (value) {
         
      return Promise.resolve(cb()).then(function () {
         
        return value
      })
    }, function (err) {
         
      return Promise.resolve(cb()).then(function () {
         
        throw err
      })
    })
    }
    
  • Promise.any():
    可用于以并行和竞争方式执行独立的异步操作,以获取任何第一个完成的 promise 的值。

应用场景:1.在页面中,我们可能需要同时请求多个接口,并且只要其中任意一个接口请求成功即可展示数据。

2.在某些情况下,我们需要在一定时间内获取某些数据或执行一系列操作,如果超过了指定时间还没完成,就需要执行后续处理。这时候,我们可以使用 Promise.race 来设置超时时间,但是这样只能处理一个任务,在需要处理多个任务的情况下,我们可以使用 Promise.any 来实现

Promise.any = function(promiseArr) {
   
    let index = 0
    return new Promise((resolve, reject) => {
   
        if (promiseArr.length === 0) return 
        promiseArr.forEach((p, i) => {
   
            Promise.resolve(p).then(val => {
   
                resolve(val)

            }, err => {
   
                index++
                if (index === promiseArr.length) {
   
                  reject(new AggregateError('All promises were rejected'))
                }
            })
        })
    })
}
相关文章
|
7月前
|
存储 前端开发 JavaScript
【面试题】Promise只会概念远远不够,还需这17道题目巩固!
【面试题】Promise只会概念远远不够,还需这17道题目巩固!
|
7月前
|
存储 前端开发 JavaScript
【面试题】面试官问:如果有100个请求,你如何使用Promise控制并发?
【面试题】面试官问:如果有100个请求,你如何使用Promise控制并发?
152 0
|
7月前
|
前端开发 JavaScript API
【面试题】说说 Promise是什么?如何使用
【面试题】说说 Promise是什么?如何使用
105 0
|
7月前
|
前端开发
【面试题】吃透Promise?先实现一个再说(包含所有方法)(二)
【面试题】吃透Promise?先实现一个再说(包含所有方法)(二)
|
7月前
|
存储 运维 前端开发
【面试题】吃透Promise?先实现一个再说(包含所有方法)(一)
【面试题】吃透Promise?先实现一个再说(包含所有方法)(一)
|
7月前
|
前端开发 JavaScript
【面试题】async/await、promise和setTimeout的执行顺序
【面试题】async/await、promise和setTimeout的执行顺序
101 0
|
7月前
|
存储 前端开发 JavaScript
面试官问:如果有100个请求,你如何使用Promise控制并发?
面试官问:如果有100个请求,你如何使用Promise控制并发?
383 0
|
7月前
|
前端开发 JavaScript
No101.精选前端面试题,享受每天的挑战和学习(Promise)
No101.精选前端面试题,享受每天的挑战和学习(Promise)
|
7月前
|
存储 前端开发 JavaScript
面试官:请手写一个Promise
面试官:请手写一个Promise
|
7月前
|
前端开发 JavaScript API
【面试题】面试官:为什么Promise中的错误不能被try/catch?
【面试题】面试官:为什么Promise中的错误不能被try/catch?