一篇精简的文章,概括Promise

69 阅读3分钟
  • 1.Promise是什么?

    • Promise 一个 构造函数, 用于创建Promise对象

      • Promise对象:可以理解为一个处理异步操作的容器
  • 2.Promise作用:解决回调地狱

    • 回调地狱:异步回调 层层嵌套

Promise特点介绍(原理篇)

promise本质 不是控制 异步代码的执行顺序(无法控制) , 而是控制异步代码结果处理的顺序

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

image.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 


下面一篇代码可以更好的了解Promise


//(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);
});

axios底层基于promise

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script>
        /* 
        1.axios() : 返回值是promise实例对象
        2.axios() : 底层是基于promise技术封装xhr
        */

        //手写axios底层原理
        function axios(obj){
            return new Promise((resolve,reject)=>{
                //(1).实例化ajax对象
                let xhr = new XMLHttpRequest()
                //(2).设置请求方法和地址ii
                //get请求的数据直接添加在url的后面 格式是 url?key=value
                xhr.open('get', obj.url )
                //(3).发送请求
                xhr.send()
                //(4).注册回调函数
                xhr.onload = function() {
                    resolve( JSON.parse(xhr.responseText) )
                }
            })
        }

        // const p1 = axios()// axios()方法本质是创建promise对象并返回
        // console.log( p1 )//promise实例对象

        Promise.all( [axios({url:'https://autumnfish.cn/api/joke/list?num=10'}) , axios({url:'https://autumnfish.cn/fruitApi/fruits'})] ).then(res=>{
            console.log(res)
        })
        
    </script>
</body>
</html>

ES6异步函数async与await

异步函数async相当于是promise语法的 “高级写法”

ES2017中引入的更为高级的异步处理机制,async函数,可以让异步的处理变的更加便捷

传送门:阮一峰-async函数

  • (1)函数前面使用async修饰

  • (2) 函数内部,promise操作使用await修饰

    • await 后面是promise对象, 左侧的返回值就是这个promise对象的then方法中的结果
    • await必须要写在async修饰的函数中,不能单独使用,否则程序会报错

以下代码可以看看Promise和异步函数async的区别


/* 
promise实例对象的catch方法 : 用于捕获异步操作的错误信息
*/


//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.

// async和await异步函数 :  这两个关键字只能用于函数, 所以用的时候一定要放在函数里面用

/* 
async关键字:  修饰函数。  表示这个函数内部有异步操作。 
await关键字:  等待异步执行完毕。
    (1)await只能用于被async修饰的函数中。  
        只有当await后面的异步操作执行完毕后,才会继续执行后面代码
    (2)await 后面 只能是promise对象
*/

const readFile = async () => {
    
    let data1 = await getPromise('a')
    console.log(data1)

    let data2 = await getPromise('b')
    console.log(data2)

    //async异步函数的错误信息要用try-catch来捕捉
    try {
        let data3 = await getPromise('c')
        console.log(data3)
    } catch (err) {
        console.log(err)

    }
}

readFile()