当前位置: 首页 > news >正文

Promise详解与基础实现(Promise/A+规范)

概述

Promise是异步编程的一种解决方案,可以替代传统的解决方案--回调函数和事件。

ES6统一了用法,并原生提供了Promise对象。作为对象,Promise有一下两个特点:

  • 对象的状态不受外界影响。
  • 一旦状态改变了就不会在变,也就是说任何时候Promise都只有一种状态。

Promise与callback相比可以避免多个异步嵌套,降低代码复杂性。

Promise 的状态

一个 Promise 的当前状态必须为以下三种状态中的一种

任务状态

结果

等待态(pending)

挂起:任务在初始状态,未完成

执行态(fulfilled/resolved)

已解决:任务结束,成功完成

拒绝态(rejected)

被拒绝:任务结束,失败了

    let p = new Promise((resolve, reject) => {
        return; //Promise {<pending>}
        //resolve('成功'); //Promise {<fulfilled>: '正确'}
        //reject('失败'); //Promise {<rejected>: '错误'}
    })

Promise 原型

    //promise 原型
    console.log(Promise.prototype);

Promise构造函数的原型上的thencatchfinally方法可以进行任务结束后的下一步操作,每个Promise实例也可以使用。

then:然后,任务成功结束的后续操作在then方法中完成。

(Promise的then支持链式调用,Promise的then方法会返回一个Promise类型的对象,从而可以继续调用then)

catch:捕获,任务失败结束的后续操作在catch方法中完成。

(注意:Promise中出现代码写错误,程序内部会throw Error,程序崩溃,但是这个catch也有捕获的能力,最终出现代码错也不会崩溃。)

finally:方法用于指定不管 Promise 对象最后状态如何,都会执行的操作

(finally方法的回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise 状态到底是fulfilled还是rejected。这表明,finally方法里面的操作,应该是与状态无关的,不依赖于 Promise 的执行结果。)

p.then(
  function(value) { /* 成功时的代码 */ },
  function(error) { /* 出错时的代码 */ }
).catch((error)=>{
  console.log(error);
  console.log("是失败了");
}).finally(() => {···});;
    let p = new Promise((resolve, reject) => {
        resolve('p成功');
    })

    let p1 = p.then(res => {
        console.log(res);
        return ('p1成功')
    }, err => {
        console.log(err);
    })
    p1.then(res => {
        console.log(res);
    })

Promise 实例

console.dir(Promise);

 Promise.all()

 Promise.all()方法就是检测参数数组内部的所有Promise实例是否成功,若成功,则调用then方法进行处理,否则变为reject状态。

    let p1 = new Promise((resolve, reject) => {
        resolve('正确');
        // reject('错误');
    })
    let p2 = new Promise((resolve, reject) => {
        resolve('正确');
        // reject('错误');
    })

    let promiseAll = Promise.all([p1, p2]);
    promiseAll.then(data => {
        console.log('圆满结束', data);
    }).catch(err => {
        console.log(err);
    })

Promise.race()

Promise.race()方法类似于 抢答,只要Promise实例之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

    let p1 = new Promise((resolve, reject) => {
        // resolve('正确');
        reject('错误');
    })
    let p2 = new Promise((resolve, reject) => {
        resolve('正确');
        // reject('错误');
    })

    let promiseAll = Promise.race([p1, p2]);
    promiseAll.then(data => {
        console.log('圆满结束', data);
    }).catch(err => {
        console.log(err);
    })

Promise.any()

Promise.any()主要是针对只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态。

    let p1 = new Promise((resolve, reject) => {
        // resolve('正确');
        reject('错误');
    })
    let p2 = new Promise((resolve, reject) => {
        resolve('正确');
        // reject('错误');
    })

    let promiseAll = Promise.any([p1, p2]);
    promiseAll.then(data => {
        console.log('圆满结束', data);
    }).catch(err => {
        console.log(err);
    })

 Promise.allSettled()

Promise.allSettled()方法接受一个数组作为参数,数组的每个成员都是一个 Promise 对象,并返回一个新的 Promise 对象。只有等到参数数组的所有 Promise 对象都发生状态变更(不管是fulfilled还是rejected),返回的 Promise 对象才会发生状态变更。

    let p1 = new Promise((resolve, reject) => {
        // resolve('正确');
        reject('错误');
    })
    let p2 = new Promise((resolve, reject) => {
        resolve('正确');
        // reject('错误');
    })

    let promiseAll = Promise.allSettled([p1, p2]);
    promiseAll.then(data => {
        console.log('圆满结束', data);
    }).catch(err => {
        console.log(err);
    })

 总结

  • Promise.all() 全成功我成功 失败一个我失败
  • Promise.race() 谁第一个改变状态就是谁的,无论成功或失败
  • Promise.any() 一个成功我成功,全部失败我失败
  • Promise.allSettled() 管你成功或失败,全部都得运行完

基础实现

    class Promise {
        state = 'pending' //增加状态
        value = null;//保存结果
        callbacks = [];
        constructor(cb) {
            const resolve = (data) => {
                this.state = "fulfilled"
                this.value = data;//保存结果
                //保证在 resolve 执行时,then方法的 onFulfilled 已经注册完成。
                this.callbacks.forEach(fn => fn(data));
            }
            const reject = (err) => {
                this.state = "rejected"
                this.value = err;//保存结果
                this.callbacks.forEach(fn => fn(data));
            }
            cb(resolve, reject)
        }
        then = (onFulfilled) => {
            if (this.state === 'pending') {//在resolve|reject之前,添加到callbacks中
                this.callbacks.push(onFulfilled);
            } else {//在resolve之后,直接执行回调,返回结果了
                onFulfilled(this.value);
            }
            return this;
            // return new Promise(() => { })
        }
        catch = (() => {
        })
        static all = () => {
        }
    }
    let p = new Promise((resolve, reject) => {
        resolve('成功')
    })

    let p1 = p.then(res => {
        console.log('then1', res);
    })

 

相关文章:

  • 封装和static
  • LF-YOLO: A Lighter and Faster YOLO for Weld Defect Detection of X-ray Image
  • JavaScript随手笔记---保留小数位
  • 检查网络端口是否正常
  • 基于JavaSwing开发房产管理系统(access数据库) 课程设计 大作业
  • [面试直通版]操作系统之编程语言与运行原理(下)
  • DFP 数据转发协议规则说明
  • Qt开发经验小技巧246-250
  • 《算法导论》第14章-数据结构的扩张 14.1-动态顺序统计 14.2-如何扩张数据结构
  • 前端面试丨综合整理中高级前端最新面试题
  • 大端与小端
  • GBase 8c 数据库内置角色
  • 无需训练、APP可玩,商品、车辆、菜品20+场景一键识别
  • 【Linux 基础笔记】(一)
  • Notion + CloudFlare + 域名搭建网站
  • [iOS]Core Data浅析一 -- 启用Core Data
  • C学习-枚举(九)
  • Docker 笔记(2):Dockerfile
  • Invalidate和postInvalidate的区别
  • Java面向对象及其三大特征
  • JS函数式编程 数组部分风格 ES6版
  • learning koa2.x
  • redis学习笔记(三):列表、集合、有序集合
  • vue自定义指令实现v-tap插件
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 记一次删除Git记录中的大文件的过程
  • 腾讯大梁:DevOps最后一棒,有效构建海量运营的持续反馈能力
  • 源码安装memcached和php memcache扩展
  • 责任链模式的两种实现
  • 阿里云服务器购买完整流程
  • 测评:对于写作的人来说,Markdown是你最好的朋友 ...
  • ​卜东波研究员:高观点下的少儿计算思维
  • #《AI中文版》V3 第 1 章 概述
  • #Linux(权限管理)
  • #我与Java虚拟机的故事#连载03:面试过的百度,滴滴,快手都问了这些问题
  • (2020)Java后端开发----(面试题和笔试题)
  • (分布式缓存)Redis分片集群
  • (四)linux文件内容查看
  • (转)eclipse内存溢出设置 -Xms212m -Xmx804m -XX:PermSize=250M -XX:MaxPermSize=356m
  • (转)ORM
  • ******之网络***——物理***
  • .[hudsonL@cock.li].mkp勒索病毒数据怎么处理|数据解密恢复
  • .net core 3.0 linux,.NET Core 3.0 的新增功能
  • .Net(C#)自定义WinForm控件之小结篇
  • .NET8.0 AOT 经验分享 FreeSql/FreeRedis/FreeScheduler 均已通过测试
  • .net程序集学习心得
  • .net和php怎么连接,php和apache之间如何连接
  • .sh
  • @RequestBody与@ModelAttribute
  • [Android]RecyclerView添加HeaderView出现宽度问题
  • [AutoSar]BSW_Com07 CAN报文接收流程的函数调用
  • [BZOJ] 3262: 陌上花开
  • [E链表] lc83. 删除排序链表中的重复元素(单链表+模拟)
  • [FTP]pureftp部署和优化
  • [HNOI2008]玩具装箱toy