乐趣区

关于前端:前端一文彻底学会Promise

作者:D827

起源:恒生 LIGHT 云社区

没有一个性能是看了源码后,还不会用的。所以看完本篇文章,心愿能帮忙你彻底把握 Promise。

Promise 的介绍

Promise 对象是 ES6 提供的实现异步的一个解决方案,它使得异步办法能够像同步办法那样返回值。

promise 是一个 构造函数 包裹(封装)一个 异步函数 (ajax; 定时器;数据库读取;fs 文件读取),当然它也能够包裹一个非异步函数。入参为两个 函数 resolve、reject。胜利调用 resolve,并传递参数,失败调用 reject,并传递参数。应用.then 来作为 回调后果的解决 ,then 承受两个 函数参数,第一个参数承受正确的返回后果,第二个函数接管谬误的返回后果。

Promise 三种状态:pending、fullfilled/resolved、rejected

Promise 初始状态为 pending,通过 resolve 办法将状态批改为 fullfilled/resolved; 通过 reject 将状态批改为 rejected

promise 的长处:它可能实现链式调用,解决了回调实现异步导致的回调天堂问题。

promise 的毛病:

  1. 无奈监测进行状态、新建立刻执行且无奈勾销;
  2. 如果不设置回调函数,Promise 外部抛出的谬误,不会反馈到内部;
  3. 有时会造成多个 then 的链式调用,可能会造成代码的语义不够明确。

Promise 的根本应用

function sleep(data){return new Promise((resolve,reject)=>{
    // new Promise 包裹的能够是一个异步的代码,也能够是一个同步的代码
    // 代码执行胜利
        setTimeOut(()=>{
               let result = null
            if(1){resolve(result)  
            }else{reject(result) 
            } 
        },1000)
})
}
sleep(1000).then(v=>{// 正确返回解决},e=>{// 谬误返回解决}).then(v=>{}).then(v=>{})
……
.catch(e=>{// 错误处理})

自定义 Promise 须要留神的问题,及解答

  1. promise 如何批改状态

    通过调用 resolve、reject 批改状态

  2. 屡次调用 resolve、reject 能够批改状态吗

    不能够,当从 pending 批改为 resolved 或者 rejected 后无奈再次批改为其余状态

  3. promise 是先批改状态还是显示执行 then,以及什么时候失去数据

    两种状况都可能呈现,当 promise 包裹的内容为异步时先指定 then 再批改状态,反之先批改状态再执行 then;

    数据是在执行完回调后获取。

  4. promise.then 返回一个 promise,这个返回的类型后果由谁决定

    返回的为 promise,由返回的 promise 决定

    返回为非 promise,则返回为 resolved

  5. promise 如何串联多个操作工作

    因为 promise.then 返回的是一个新的 Promise 对象,所以还能够调用 then,实现链式调用

  6. promise 异样穿透

    意思是不管有多少个 then,两头任意一个 then 呈现报错都会被 catch 捕捉

  7. 如何终止 promise 链

    then 中任意一个出现异常;

    在任意 then 中将 promise 的状态改为 pending。

Promise 的自定义

 // 申明构造函数
 function Promise(executor){
     // 增加属性
     this.PromiseState = 'pending';
     this.PromiseResult = null;
     // 申明属性 回调存在多个状况
     this.callbacks = [];
     // 保留实例对象的 this 的值
     const self = this;// self _this that
     //resolve 函数
     function resolve(data){
         // 判断状态 屡次调用 resolve、reject 不能够批改状态
         if(self.PromiseState !== 'pending') return;
         //1. 批改对象的状态 (promiseState)
         self.PromiseState = 'fulfilled';// resolved
         //2. 设置对象后果值 (promiseResult)
         self.PromiseResult = data;
         // 调用胜利的回调函数
         setTimeout(() => {
             self.callbacks.forEach(item => {item.onResolved(data);
             });
         });
     }
     //reject 函数
     function reject(data){
         // 判断状态
         if(self.PromiseState !== 'pending') return;
         //1. 批改对象的状态 (promiseState)
         self.PromiseState = 'rejected';// 
         //2. 设置对象后果值 (promiseResult)
         self.PromiseResult = data;
         // 执行失败的回调
         setTimeout(() => {
             self.callbacks.forEach(item => {item.onRejected(data);
             });
         });
     }
     try{
         // 同步调用『执行器函数』executor(resolve, reject);
     }catch(e){
         // 批改 promise 对象状态为『失败』reject(e);
     }
 }
 
 // 增加 then 办法
 Promise.prototype.then = function(onResolved, onRejected){
     const self = this;
     // 判断回调函数参数
     if(typeof onRejected !== 'function'){
         onRejected = reason => {throw reason;}
     }
     if(typeof onResolved !== 'function'){
         onResolved = value => value;
         //value => {return value};
     }
     return new Promise((resolve, reject) => {
         // 封装函数
         function callback(type){
             try{
                 // 获取回调函数的执行后果
                 let result = type(self.PromiseResult);
                 // 判断
                 if(result instanceof Promise){
                     // 如果是 Promise 类型的对象
                     result.then(v => {resolve(v);
                     }, r=>{reject(r);
                     })
                 }else{
                     // 后果的对象状态为『胜利』resolve(result);
                 }
             }catch(e){reject(e);
             }
         }
         // 调用回调函数  PromiseState
         if(this.PromiseState === 'fulfilled'){setTimeout(() => {callback(onResolved);
             });
         }
         if(this.PromiseState === 'rejected'){setTimeout(() => {callback(onRejected);
             });
         }
         // 判断 pending 状态
         if(this.PromiseState === 'pending'){
             // 异步状况下保留回调函数 在异步执行完结后执行回调函数
             this.callbacks.push({onResolved: function(){callback(onResolved);
                 },
                 onRejected: function(){callback(onRejected);
                 }
             });
         }
     })
 }
 
 // 增加 catch 办法
 Promise.prototype.catch = function(onRejected){return this.then(undefined, onRejected);
 }
 
 // 增加 resolve 办法
 Promise.resolve = function(value){
     // 返回 promise 对象
     return new Promise((resolve, reject) => {if(value instanceof Promise){
             value.then(v=>{resolve(v);
             }, r=>{reject(r);
             })
         }else{
             // 状态设置为胜利
             resolve(value);
         }
     });
 }
 
 // 增加 reject 办法
 Promise.reject = function(reason){return new Promise((resolve, reject)=>{reject(reason);
     });
 }
 
 // 增加 all 办法
 Promise.all = function(promises){
     // 返回后果为 promise 对象
     return new Promise((resolve, reject) => {
         // 申明变量
         let count = 0;
         let arr = [];
         // 遍历
         for(let i=0;i<promises.length;i++){
             //
             promises[i].then(v => {
                 // 得悉对象的状态是胜利
                 // 每个 promise 对象 都胜利
                 count++;
                 // 将以后 promise 对象胜利的后果 存入到数组中
                 arr[i] = v;
                 // 判断
                 if(count === promises.length){
                     // 批改状态
                     resolve(arr);
                 }
             }, r => {reject(r);
             });
         }
     });
 }
 
 // 增加 race 办法
 Promise.race = function(promises){return new Promise((resolve, reject) => {for(let i=0;i<promises.length;i++){promises[i].then(v => {
                 // 批改返回对象的状态为『胜利』resolve(v);
             },r=>{
                 // 批改返回对象的状态为『失败』reject(r);
             })
         }
     });
 }

心愿以上内容对你有所帮忙!


想向技术大佬们多多取经?开发中遇到的问题何处探讨?如何获取金融科技海量资源?

恒生 LIGHT 云社区,由恒生电子搭建的金融科技业余社区平台,分享实用技术干货、资源数据、金融科技行业趋势,拥抱所有金融开发者。

扫描下方小程序二维码,退出咱们!

退出移动版