Promise对象 简单理解记录

108 阅读4分钟

首先 我们先从3个方面去了解

1.promise是什么?

MDN官网是这样描述的:

一个Promise对象代表在创建程序时发现了这个特定功能的值的代理。它让你被操作失败或者最终的成功返回失败。那样返回值:随便的方法并不会立即返回结果的值,而是会返回一个promise,以便在未来的时候把值给用户。

简单点说就是:

Promise 可以理解为是一个处理异步操作的容器 它是 一个 构造函数, 用于创建Promise对象

2.promise的作用和使用方法详解

它的作用大家都知道 就是为了解决回调地狱 (异步回调,层层嵌套)

可读性高 易于维护 你可以永远相信promise 它的状态只会改变一次且不可逆

它的基本使用方法:

1.实例化Promise对象

作用:将异步操作代码放入Promise'容器'中

  • resolve:异步操作 成功状态
  • reject : 异步操作 失败状态
  • new Promise((resolve,reject)=>{你的异步操作})

2.调用then()方法来处理异步操作结果

  • promise对象.then((data)=>{ 处理成功数据 },(err)=>{ 处理失败信息 })

  • 在没有Promise之前我们想要异步操作有序执行需要用回调地狱封装 非常麻烦且不便于维护 而Promise就是来解决这一点的

下面用代码来解释大家好理解一点

/* 
1.Promise作用 : 解决回调地狱问题
    回调地狱 : 异步回调 层层嵌套
*
//需求: 依次读取 文件  a.txt , b.txt , c.txt 这三个文件内容
const fs = require('fs');
//解决方案 : 在回调函数中嵌套执行
//弊端 : 形成回调地狱(异步回调 层层嵌套,非常麻烦且不便于维护)
//读取文件A
fs.readFile("./data/a.txt", 'utf-8', (err, data) => {
    if(err){
        console.log(err);
    }else{
        console.log(data);
        //A读取成功之后开始读取B
        fs.readFile("./data/b.txt", 'utf-8', (err, data) => {
            if(err){
                console.log(err);
            }else{
                console.log(data);
                //B读取成功之后开始读取C
                fs.readFile("./data/c.txt", 'utf-8', (err, data) => {
                    if(err){
                        console.log(err);
                    }else{
                        console.log(data);
                    }
                });
            }
        });
    }
});



//接下来我们使用promise解决回调地狱封装
//1.封装一个函数 :  根据文件名生成  文件读取的promise
function getPromise(fileName) {
    let p = new Promise((resolve, reject) => {
        //读文件
        fs.readFile(`./data/${fileName}.txt`,'utf-8', (err, data) => {
            if (err == null) {
                //成功
                resolve(data);
            } else {
                //失败
                reject(err);
            }
        });
    });
    return p;
};

//2.解决需求: 要先读a, 读完a后读b, 读完b后读c.

//开始读取a
getPromise('a').then((data)=>{
    console.log(data);
    //继续读取b
    return getPromise('b');
}).then((data)=>{
    console.log(data);
    //继续读取c
    return getPromise('c');
}).then((data)=>{
    console.log(data);
});//异步回调队列结束

补充 : Promise对象的3个方法

  • Promise对象的catch方法: 用于捕获异步操作的错误信息
  • Promise对象的all方法: 将多个Promise合并成一个Promise, 所有异步全部执行完毕才会执行then方法,
  • Promise对象的race方法: 将多个Promise合并成一个Promise, 任何一个异步 执行完毕就会执行then方法

3.promise的特点及原理

了解了Promise的使用方法再来了解下它的底层逻辑吧

  • Promise本身只是一个容器,真正异步的是它的两个回调resolve()和reject()

Snipaste_2022-09-12_20-36-49.png

/**
 * 1.promise对象有三个状态.
    a. pending(进行中)
    b. fulfilled(已成功)
    c. rejected(已失败)
 
 * 2.Promise对象的状态改变, 只有两种可能:
    a. 从pending变为fulfilled
        * 此时应该执行 resolve();
    b. 从pending变为rejected。
        * 此时应该执行 reject();
 
 * 3.promise在创建对象的时候,里面的代码会立即执行.
    a. promise创建时,里面的代码还是异步无序操作
    b. promise的原理是,利用then方法将异步操作的结果 按照顺序执行
    *** 总结: 不要在创建promise的时候去处理异步操作结果,而应该通过 then() 方法来处理 ***

 * 4.promise解决回调地狱原理 : 在then方法中返回一个promise对象
    *** 在上一个promise的then方法中,返回下一个promise ***

 

const fs = require('fs');

//(1) 创建三个异步操作  promise

//读取文件A
const p1 = new Promise((resolve,reject)=>{
    //读文件
    fs.readFile('./data/a.txt','utf8',(err,data)=>{
       if(err == null){ 
            //成功
           resolve(data);
       }else {
           //失败
           reject(err); 
       }
    });
});

//读取文件B
const p2 = new Promise((resolve,reject)=>{
    //读文件
    fs.readFile('./data/b.txt','utf8',(err,data)=>{
       if(err == null){ 
            //成功
           resolve(data);
       }else {
           //失败
           reject(err); 
       }
    });
});

//读取文件C
const p3 = new Promise((resolve,reject)=>{
    //读文件
    fs.readFile('./data/c.txt','utf8',(err,data)=>{
       if(err == null){ 
            //成功
           resolve(data);
       }else {
           //失败
           reject(err); 
       }
    });
});

// (2)按照顺序处理异步操作结果
p1.then((data)=>{//第一个异步结果
    console.log(data);
    return p2;//返回下一个promise
}).then((data)=>{ // 第二个异步结果  (由于p1.then方法返回的是p2,而p2也有自己的then,所以可以继续调用p2的then方法)
    console.log(data);
    return p3;//返回下一个promise
}).then((data)=>{ // 第三个异步结果  
    console.log(data);
});

  • 结语 :Promise本质上无法改变它的执行顺序(无法控制),而是通过操作执行结果(then()回调)来间接控制执行顺序