对于Promise的一点理解

时间:2021-2-20 作者:admin
  • Promise的作用
  • Promise使用流程
  • Promise原理及注意点
  • Promise其他用法

本文总结一下自己对于Promise的一点理解

Promise的作用

解决回调地狱;而这又涉及到另一个知识点,即何为回调地狱?

回调地狱

异步回调,层层嵌套;

以下代码就是回调地狱:

//需求:依次读取abcd文件内容
/* 异步代码有序执行 : 异步嵌套 */

const fs = require('fs');

//1.读取文件a
fs.readFile(`${__dirname}/data/a.txt`, 'utf8', (err, data) => {
    if (err) {
        throw err;
    } else {
        console.log(data);
        //2.读取文件b
        fs.readFile(`${__dirname}/data/b.txt`, 'utf8', (err, data) => {
            if (err) {
                throw err;
            } else {
                console.log(data);
                //3.读取文件c
                fs.readFile(`${__dirname}/data/c.txt`, 'utf8', (err, data) => {
                    if (err) {
                        throw err;
                    } else {
                        console.log(data);
                        //4.读取文件d
                        fs.readFile(`${__dirname}/data/d.txt`, 'utf8', (err, data) => {
                            if (err) {
                                throw err;
                            } else {
                                console.log(data);
                            }
                        });
                    }
                });
            }
        });
    }
});

Promise使用流程

Promise是一个构造函数,用于创建实例对象

  1. 创建promise实例对象 : let p = new Promise( (resolve,reject)=>{ //异步操作 });
  2. 调用实例对象的then方法 : p.then(data=>{},err=>{})

使用Promise解决回调地狱

//需求:依次读取abcd文件内容
/* 异步代码有序执行 : 异步嵌套 */

const fs = require('fs');


//1 创建promise实例对象 :  let p = new Promise();
let p1 = new Promise((resolve, reject) => {
    //异步操作
    fs.readFile(`${__dirname}/data/a.txt`, 'utf8', (err, data) => {
        if (!err) {//成功
            /* 
            (1)异步操作成功:调用resolve()
            (2)调用resolve()本质调用then()方法第一个函数
            */
            resolve(data);
        } else {
            /* 
            (1)异步操作失败:调用reject()
            (2)reject()本质调用then()方法第二个函数
            */
            reject(err);
        }
    });
});

let p2 = new Promise((resolve, reject) => {
    //异步操作
    fs.readFile(`${__dirname}/data/b.txt`, 'utf8', (err, data) => {
        if (!err) {//成功
            resolve(data);
        } else {
            reject(err);
        }
    });
});

let p3 = new Promise((resolve, reject) => {
    //异步操作
    fs.readFile(`${__dirname}/data/c.txt`, 'utf8', (err, data) => {
        if (!err) {//成功
            resolve(data);
        } else {
            reject(err);
        }
    });
});

let p4 = new Promise((resolve, reject) => {
    //异步操作
    fs.readFile(`${__dirname}/data/d.txt`, 'utf8', (err, data) => {
        if (!err) {//成功
            resolve(data);
        } else {
            reject(err);
        }
    });
});



//2 调用实例对象的then方法 : p.then()
//第一个参数: 异步成功需要执行的函数  第二个参数:异步失败需要执行的函数
p1.then(data => {
    console.log(data);
    return p2;//在p1的then方法中返回p2
})
.then(data=>{//p2的then
    console.log(data);
    return p3;
})
.then(data=>{//p3的then
    console.log(data);
    return p4;
})
.then(data=>{//p4的then
    console.log(data);
});


Promise解决回调地狱函数封装

//需求:依次读取abcd文件内容
/* 异步代码有序执行 : 异步嵌套 */

const fs = require('fs');


function createPromise(filename){
    return new Promise((resolve,reject)=>{
        fs.readFile(`${__dirname}/data/${filename}.txt`, 'utf8', (err, data) => {
            if (!err) {//成功
                resolve(data);
            } else {
                reject(err);
            }
        });
    });;
}


//1 创建promise实例对象 :  let p = new Promise();
let p1 = createPromise('a');

let p2 = createPromise('b');

let p3 = createPromise('c');

let p4 = createPromise('d');


//2 调用实例对象的then方法 : p.then()
//第一个参数: 异步成功需要执行的函数  第二个参数:异步失败需要执行的函数
p1.then(data => {
    console.log(data);
    return p2;//在p1的then方法中返回p2
})
.then(data=>{//p2的then
    console.log(data);
    return p3;
})
.then(data=>{//p3的then
    console.log(data);
    return p4;
})
.then(data=>{//p4的then
    console.log(data);
});

Promise原理及注意点

Promise对象有三种状态

  • pending(进行中)
  • fulfilled(已成功)
  • rejected(已失败)

在阮一峰的es6手册中,他将Promise举例成容器,我对容器还不太理解;所以,此处我通过将Promise举例成中介的方式来理解它

Promise的三种状态可以举例成中介办事的三种状态,比如我们需要办理车辆过户(事物),一旦我们交给Promise/中介之后,只有异步操作/中介办理的结果,可以决定当前是哪一种状态,且无法更改;

  • 正在办理 -> pending(进行中)
  • 办理完成 -> fulfilled(已成功)
  • 办理失败 -> rejected(已失败)

Promise状态改变只有两种情况

  • 从 pending(进行中) -> fulfilled(已成功)
  • 从 pending(进行中) -> rejected(已失败)

此处也与中介的办理流程类比,在办理的过程中你向中介致电,也只会得到以上两种情况

  • 正在办 -> 办理成功(执行成功回调/交接证件资料等)
  • 正在办 -> 办理失败(执行错误回调/告知办理失败的原因)

Promise一旦创建,异步就会立即执行。

Promise一旦创建,异步就会立即执行。对应的,中介一旦收费,就会立即执行.

  • 不要在Promise里面去获取异步结果,因为异步本身还是无序的
  • 应该通过then方法去获取异步结果

Promise如何控制异步顺序

在上一个promise实例对象的then()方法中返回下一个promise实例对象

一点理解

Promise(容器/中介)本质不是修改异步的顺序(异步永远都是无序的),而是通过控制异步结果的顺序从而间接控制异步的顺序。

Promise其他用法

catch

用于捕捉promise的错误信息

//需求:依次读取abcd文件内容
/* 异步代码有序执行 : 异步嵌套 */

const fs = require('fs');


function createPromise(filename){
    return new Promise((resolve,reject)=>{
        fs.readFile(`${__dirname}/data/${filename}.txt`, 'utf8', (err, data) => {
            if (!err) {//成功
                resolve(data);
            } else {
                reject(err);
            }
        });
    });;
};


//1 创建promise实例对象 :  let p = new Promise();
let p1 = createPromise('a');

let p2 = createPromise('b');

let p3 = createPromise('c');

let p4 = createPromise('d');


//将多个promise放入数组中, 只有数组中所有的promise执行完毕才会执行all的then方法
let pAll =  Promise.all([p1,p2,p3,p4]);

//2 调用实例对象的then方法 : p.then()
//第一个参数: 异步成功需要执行的函数  第二个参数:异步失败需要执行的函数

p1.then(data => {
    console.log(data);
    return p2;//在p1的then方法中返回p2
})
.then(data=>{//p2的then
    console.log(data);
    return p3;
})
.then(data=>{//p3的then
    console.log(data);
    return p4;
})
.then(data=>{//p4的then
    console.log(data);
})
.catch(err=>{
    //上面任何一个then方法出错了,就会执行这个catch方法
    console.log(err);
});

all

将多个promise放入数组中, 只有数组所有的promise执行完毕才会执行all的then方法

//需求:依次读取abcd文件内容
/* 异步代码有序执行 : 异步嵌套 */

const fs = require('fs');


function createPromise(filename){
    return new Promise((resolve,reject)=>{
        fs.readFile(`${__dirname}/data/${filename}.txt`, 'utf8', (err, data) => {
            if (!err) {//成功
                resolve(data);
            } else {
                reject(err);
            }
        });
    });;
};


//1 创建promise实例对象 :  let p = new Promise();
let p1 = createPromise('a');

let p2 = createPromise('b');

let p3 = createPromise('c');

let p4 = createPromise('d');


//将多个promise放入数组中, 只有数组中所有的promise执行完毕才会执行all的then方法
let pAll =  Promise.all([p1,p2,p3,p4]);

//2 调用实例对象的then方法 : p.then()
//第一个参数: 异步成功需要执行的函数  第二个参数:异步失败需要执行的函数
pAll.then(data=>{
    /* 执行时机:数组中所有的promise执行完毕 */
    //data: 数组。 存储对应的promise的data数据
    console.log(data);
})
.catch(err=>{
    //上面任何一个then方法出错了,就会执行这个catch方法
    console.log(err);
})

race

将多个promise放入数组中,只要数组中任意promise执行完毕才会执行race的then方法

//需求:依次读取abcd文件内容
/* 异步代码有序执行 : 异步嵌套 */

const fs = require('fs');


function createPromise(filename){
    return new Promise((resolve,reject)=>{
        fs.readFile(`${__dirname}/data/${filename}.txt`, 'utf8', (err, data) => {
            if (!err) {//成功
                resolve(data);
            } else {
                reject(err);
            }
        });
    });;
};


//1 创建promise实例对象 :  let p = new Promise();
let p1 = createPromise('a');

let p2 = createPromise('b');

let p3 = createPromise('c');

let p4 = createPromise('d');


//将多个promise放入数组中,只要数组中任意promise执行完毕才会执行race的then
let pAll =  Promise.race([p1,p2,p3,p4]);

//2 调用实例对象的then方法 : p.then()
//第一个参数: 异步成功需要执行的函数  第二个参数:异步失败需要执行的函数
pAll.then(data=>{
    /* 执行时机:数组中第一个完成的promise */
    //data: 第一个完成的promise
    console.log(data);
})
.catch(err=>{
    //上面任何一个then方法出错了,就会执行这个catch方法
    console.log(err);
})
声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。