关于前端:前端一文彻底学会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云社区,由恒生电子搭建的金融科技业余社区平台,分享实用技术干货、资源数据、金融科技行业趋势,拥抱所有金融开发者。

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

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理