• ES6--》一文搞懂JS中的Promise


    目录

    Promise

    Promise使用

    Promise封装Ajax请求

    Promise封装读取文件

    Promise.prototype.then 方法

    Promise多文件读取

    Promise.prototype.catch()

    Promise.prototype.finally()

    Promise.all()

    Promise.race()

    Promise.allSettled()

    Pomise.any()

    Promise.resolve()


    Promise

    Promise是ES6引入的异步编程的新解决方案。语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。

    Promise特点

    Promsie对象异步操作有三种状态,pending(进行中)、fulfilled(已成功)和reject(已失败)。只有异步操作才可以决定当前是哪种状态Promise状态改变有两种可能,从pending变为fulfidded和从pending变为rejected。状态发生改变就不能再改变了,称为:resolved(已定型)

    Promise对象的作用:将异步操作以同步操作的流程表达出来,避免层层嵌套的回调函数,而且Promise提供了统一的接口,使得控制异步操作更加容易。

    Promise使用

    Promise构造函数接收一个函数作为参数,该函数的两个参数分别为:resolve 和 reject。

    resolve:在异步操作成功时调用,并将异步操作的结果作为参数传递出去。

    reject:在异步操作失败时调用,并将异步操作报出的错误作为参数传递出去。

    Promise实例生成后,可以用 then 方法分别指定 resolved 状态和 rejected 状态的回调函数;而第一个回调函数是 Promise 对象状态变 resolved 时调用,第二个回调函数是 Promise 对象的状态变为 rejected 时调用。案例如下:

    Promise新建后会立即执行,然而 then 方法指定的回调函数将在当前脚本所有同步任务执行完才会执行。

    Promise封装Ajax请求

    Promise封装读取文件

    这里借助 Node.js 方法进行读取文件,不了解Node.js的方法可以关注我,后期会出相关专栏。

    1. // 1.引入 fs 模块
    2. const fs = require('fs')
    3. // 2.调用方法读取文件
    4. // fs.readFile('./index.md',(err,data)=>{
    5. // // 如果失败,则抛出错误
    6. // if(err) throw err;
    7. // // 如果没有出错,则输出内容
    8. // console.log(data.toString());
    9. // })
    10. // 3.使用 Promise 封装
    11. const p = new Promise(function(resolve,reject){
    12. fs.readFile('./index.md',(err,data)=>{
    13. // 判断如果失败
    14. if(err) reject(err)
    15. // 如果成功
    16. resolve(data)
    17. })
    18. })
    19. p.then(function(value){
    20. console.log(value.toString());
    21. },function(reason){
    22. console.log("读取失败!!");
    23. })
    '
    运行

    Promise.prototype.then 方法

    Promise实例具有then方法,即then方法定义在原型对象Promise.prototype上,作用是为Promise实例添加状态改变时的回调函数。案例如下:

    then方法返回的是一个新的Promise实例,因此可以采用链式写法,即then方法后面再调用另一个then方法。但是前一个then()方法中的回调函数中又可能返回一个Promise实例,这时候后面一个then()方法中的回调函数会等前一个Promise实例状态发生变化才会调用。案例如下:

    Promise多文件读取

    回调地狱与Promise对象实现相比,不会产生回调现象,而且也不用再数据庞大时进行大规模的缩进。承接上文单文件读取,现在进行多文件读取,案例如下:

    1. // 1.引入 fs 模块
    2. const { rejects } = require('assert')
    3. const fs = require('fs')
    4. const { resolve } = require('path')
    5. // 2.回调地狱 调用方法读取文件
    6. // fs.readFile('./index.md',(err,data)=>{
    7. // fs.readFile('./index1.md',(err,data1)=>{
    8. // fs.readFile('./index2.md',(err,data2)=>{
    9. // let result = data + '\r\n' + data1 +'\r\n'+ data2
    10. // console.log(result);
    11. // })
    12. // })
    13. // })
    14. // 3.使用 Promise 实现
    15. const p = new Promise((resolve,reject)=>{
    16. fs.readFile('./index.md',(err,data)=>{
    17. resolve(data)
    18. })
    19. })
    20. // value 是第一个文件的内容
    21. p.then(value => {
    22. return new Promise((resolve,reject)=>{
    23. fs.readFile('./index1.md',(err,data)=>{//data是第二个文件的内容
    24. // 返回的是第一个和第二个文件合并的数组
    25. resolve([value, data])
    26. })
    27. })
    28. }).then(value => {//这里的value就是上面合并的数组
    29. return new Promise((resolve,reject)=>{
    30. fs.readFile('./index2.md',(err,data)=>{//data是第三个文件的内容
    31. // 压入
    32. value.push(data)
    33. resolve(value)
    34. })
    35. })
    36. }).then(value => {//如果上面成功,现在的value就是返回三个数组的合集
    37. console.log(value.join('\r\n'));//数组用join进行拼接
    38. })
    '
    运行

    Promise.prototype.catch()

    该方法用于指定发生错误时的回调函数。举个简单的例子:

    Promise.prototype.finally()

    finally()方法指定不管promise最后的状态如何,在执行完then或catch指定的回调函数以后,都会执行finally方法指定的回调函数。

    Promise.all()

    该方法用于将多个 Promise 实例包装成一个新的 Promise 实例,方法接受一个数组作为参数,数组参数都是Promsie实例。当然参数也可以不是数组,但必须有Iterator接口,且返回的每个成员都是Promise实例。

    该方法只适合所有异步都操作成功的情况,如果有一个操作失败就无法满足要求。

    Promise.race()

    该方法同样是将多个 Promise 实例包装成一个新的 Promsie 实例,该方法与 Promise.all()方法一样,区别是该方法中只要参数之中有一个实例率先改变状态,该方法的实例状态跟着改变,那个率先改变的 Promise 实例的返回值就传递给该方法实例的回调函数。

    上面代码中,如果 5 秒之内fetch方法无法返回结果,变量p的状态就会变成rejected,从而触发catch方法指定的回调函数。

    Promise.allSettled()

    该方法用来确定一组异步是否都结束(不管成功或失败)。方法接受一个数组作为参数,只有当参数数组中所有 Promise对象 都发生变化,返回的 Promise 对象才会发生状态变更。

    回调函数接受到的参数是数组results,该数组的每一个成员都是一个对象,对应传入Promise.allSettled()的数组里面的两个 Promsie 对象。

    Pomise.any()

    Promise.any()和Promise.race()方法很像,唯一区别就是Promise.any()不会因为某个 Promise 变成 rejected 状态而结束,必须等到所有参数 Promise 变成 rejected 状态才会结束。

    1. var resolved = Promise.resolve(42);
    2. var rejected = Promise.reject(-1);
    3. var alsoRejected = Promise.reject(Infinity);
    4. Promise.any([resolved, rejected, alsoRejected]).then(function (result) {
    5. console.log(result); // 42
    6. });
    7. Promise.any([rejected, alsoRejected]).catch(function (results) {
    8. console.log(results instanceof AggregateError); // true
    9. console.log(results.errors); // [-1, Infinity]
    10. });
    '
    运行

    Promise.resolve()

    该方法能够将现有对象转换为 Promise 对象。

    1. Promise.resolve('foo')
    2. // 等价于
    3. new Promise(resolve => resolve('foo'))
    '
    运行
  • 相关阅读:
    ATFX:白宫再抛售1500万桶战略原油储备,油价小幅承压
    electron开发桌面程序mac/window,配合vue3+vite进行配置开发
    信号量实现生产消费模型
    java的集合
    (memcpy,memmove...)内存函数还不会??别怕,我来助你一臂之力
    从数据的属性看数据资产
    新能源仓储解决方案案例|HEGERLS托盘四向穿梭车如何解决仓库地面集中载荷不够的困扰?
    在Spring Boot项目中使用JPA
    卷积神经网络卷积层池化层全连接层理解
    Numpy知识点回顾与学习
  • 原文地址:https://blog.csdn.net/qq_53123067/article/details/127087102