• Promise详解


    概述

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

    ES6统一了用法,并原生提供了Promise对象。

    Promise的两个特点:

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

    Promise的三个缺点:

    • 无法取消Promise,一旦新建它就会立即执行,无法中途取消
    • 如果不设置回调函数,Promise内部抛出的错误,不会反映到外部
    • 当处于pending状态时,无法得知目前进展到哪一个阶段,是刚刚开始还是即将完成

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

    Promise 的状态

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

    任务状态

    结果

    等待态(pending)

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

    执行态(fulfilled/resolved)

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

    拒绝态(rejected)

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

    1. let p = new Promise((resolve, reject) => {
    2. return; //Promise {}
    3. //resolve('成功'); //Promise {: '正确'}
    4. //reject('失败'); //Promise {: '错误'}
    5. })

    Promise(原形方法)

    1. //promise 原型
    2. 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 的执行结果。)

    1. p.then(
    2. function(value) { /* 成功时的代码 */ },
    3. function(error) { /* 出错时的代码 */ }
    4. ).catch((error)=>{
    5. console.log(error);
    6. console.log("是失败了");
    7. }).finally(() => {···});;
    1. let p = new Promise((resolve, reject) => {
    2. resolve('p成功');
    3. })
    4. let p1 = p.then(res => {
    5. console.log(res);
    6. return ('p1成功')
    7. }, err => {
    8. console.log(err);
    9. })
    10. p1.then(res => {
    11. console.log(res);
    12. })

    Promise(静态方法)

    console.dir(Promise);

     Promise.all()

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

    1. let p1 = new Promise((resolve, reject) => {
    2. resolve('正确');
    3. // reject('错误');
    4. })
    5. let p2 = new Promise((resolve, reject) => {
    6. resolve('正确');
    7. // reject('错误');
    8. })
    9. let promiseAll = Promise.all([p1, p2]);
    10. promiseAll.then(data => {
    11. console.log('圆满结束', data);
    12. }).catch(err => {
    13. console.log(err);
    14. })

    Promise.race()

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

    1. let p1 = new Promise((resolve, reject) => {
    2. // resolve('正确');
    3. reject('错误');
    4. })
    5. let p2 = new Promise((resolve, reject) => {
    6. resolve('正确');
    7. // reject('错误');
    8. })
    9. let promiseAll = Promise.race([p1, p2]);
    10. promiseAll.then(data => {
    11. console.log('圆满结束', data);
    12. }).catch(err => {
    13. console.log(err);
    14. })

    Promise.any()

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

    1. let p1 = new Promise((resolve, reject) => {
    2. // resolve('正确');
    3. reject('错误');
    4. })
    5. let p2 = new Promise((resolve, reject) => {
    6. resolve('正确');
    7. // reject('错误');
    8. })
    9. let promiseAll = Promise.any([p1, p2]);
    10. promiseAll.then(data => {
    11. console.log('圆满结束', data);
    12. }).catch(err => {
    13. console.log(err);
    14. })

     Promise.allSettled()

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

    1. let p1 = new Promise((resolve, reject) => {
    2. // resolve('正确');
    3. reject('错误');
    4. })
    5. let p2 = new Promise((resolve, reject) => {
    6. resolve('正确');
    7. // reject('错误');
    8. })
    9. let promiseAll = Promise.allSettled([p1, p2]);
    10. promiseAll.then(data => {
    11. console.log('圆满结束', data);
    12. }).catch(err => {
    13. console.log(err);
    14. })

     总结

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

    基础实现

    1. class Promise {
    2. state = 'pending' //增加状态
    3. value = null;//保存结果
    4. callbacks = [];
    5. constructor(cb) {
    6. const resolve = (data) => {
    7. this.state = "fulfilled"
    8. this.value = data;//保存结果
    9. //保证在 resolve 执行时,then方法的 onFulfilled 已经注册完成。
    10. this.callbacks.forEach(fn => fn(data));
    11. }
    12. const reject = (err) => {
    13. this.state = "rejected"
    14. this.value = err;//保存结果
    15. this.callbacks.forEach(fn => fn(data));
    16. }
    17. cb(resolve, reject)
    18. }
    19. then = (onFulfilled) => {
    20. if (this.state === 'pending') {//在resolve|reject之前,添加到callbacks中
    21. this.callbacks.push(onFulfilled);
    22. } else {//在resolve之后,直接执行回调,返回结果了
    23. onFulfilled(this.value);
    24. }
    25. return this;
    26. // return new Promise(() => { })
    27. }
    28. catch = (() => {
    29. })
    30. static all = () => {
    31. }
    32. }
    33. let p = new Promise((resolve, reject) => {
    34. resolve('成功')
    35. })
    36. let p1 = p.then(res => {
    37. console.log('then1', res);
    38. })

  • 相关阅读:
    牛客网解题之矩形覆盖
    【51单片机系列】C51基础
    租用国外服务器要怎么选择?
    云服务器及域名到期后,公安联网注销指南
    H3C(华三)交换堆叠/IRF配置实例
    二叉树的操作
    懒人必备爬虫神器—playwright
    【Typescript】学习笔记(二)之函数与类的使用
    整合mybatis
    作业练习2:类与数据结构
  • 原文地址:https://blog.csdn.net/qq_55172460/article/details/126840528