04-Promise

公孙和怡
2023-12-01

Promise 的理解和使用

promsie 是什么?

1、抽象表达:

  • Promise 是一门新的技术(ES6 规范)\2) Promise 是 JS 中进行异步编程的新解决方案

  • 备注:旧方案是单纯使用回调函数

2、具体表达:

  • 从语法上来说: Promise 是一个构造函数

  • 从功能上来说: promise 对象用来封装一个异步操作并可以获取其成功失败的结果值

入门案例

  • 任务要求:当用户点击button按钮时,判断用户中奖情况
  • resolve():promise 对象的状态设置为 【成功】
  • reject():promise 对象的状态设置为 【失败】

index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <h1 align="center">Promise</h1>
    <hr>
    <button>点击抽奖</button>
    <script>
        var btn = document.querySelector("button");
        var random = (n, m) => {
            return Math.ceil(Math.random() * (n - m + 1) + m + 1);
        }
        console.log(btn);
        btn.addEventListener('click', () => {
            let promise = new Promise((resolve, reject) => {
                let result = random(1, 100);
                console.log(result);
                if (result <= 30) {
                    resolve(result);
                } else {
                    reject(result);
                }value
            });value
            promise.then(value => {
                alert("哈哈哈哈哈");
            }, value => {
                alert("klasdjfklajsdflkj;");
            })
        })

    </script>
</body>

</html>

fs模块

//引入fs模块
const fs = require("fs");

//promise形式
let promise = new Promise((resolve, refect) => {
    fs.readFile('./resource/context.txt', (err, data) => {
        //错误
        if (err) throw err;
        //正常输出
        resolve(data);
    });
})

//回调函数
promise.then(result => {
    console.log(result.toString());
}, data => {
    console.log(data);
});

AJAX 请求

server.js

//1、引入express
const express = require('express');

//2、创建一个应用对象
const app = express();

//3、创建路由规则
app.get('/server', (request, response) => {
    //设置允许跨域
    response.setHeader('Access-control-Allow-Origin', '*');
    response.send("Hello Express");
})

//4、监听端口启动服务
app.listen(8000, () => {
    console.log("服务已经启动 8000端口监听中");
})

index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <h1 algin="center">promise</h1>
    <hr>
    <button>看这里</button>
    <script>
        var btn = document.querySelector("button");

        btn.addEventListener('click', () => {
            //promise
            let promise = new Promise((resolve, refect) => {
                //1、创建对象
                let xml = new XMLHttpRequest();
                //2、初始化
                xml.open("GET", "http://127.0.0.1:8000/server");
                //3、发送
                xml.send();
                //4、绑定事件,处理服务器返回的相应结果
                xml.onreadystatechange = () => {
                    //判断响应值
                    if (xml.readyState === 4) {
                        //判断响应码
                        if (xml.status >= 200 && xml.status < 300) {
                            resolve(xml.response);
                        } else {
                            refect(xml.status);
                        }
                    }
                }
            })

            promise.then(value => {
                console.log(value);
            }, result => {
                console.log(result);
            })
        })
    </script>
</body>

</html>

封装fs读取文件操作

function mineReadFile(path) {
    return new Promise((resolve, reject) => {
        require('fs').readFile(path, (err, data) => {
            if (err) reject(err);
            resolve(data);
        })
    })
}

mineReadFile('./resource/context.txt').then(value => {
    console.log(value.toString());
}, reason => {
    console.log(reason);
})

util.promisify方法进行promise风格

const util = require('util');

const fs = require('fs');

let mineReadFile = util.promisify(fs.readFile);

mineReadFile('./resource/context.txt').then(value => {
    console.log(value.toString());
})

promise 的状态改变

【PromiseState】

  • promise的状态是实例对象中的一个属性【PromiseState】

1、pending 变为 resolved

2、pending 变为 rejected

  • 说明: 只有这 2 种, 且一个 promise 对象只能改变一次 无论变为成功还是失败, 都会有一个结果数据成功的结果数据一般称为 value, 失败的结果数据一般称为 reason

【PromiseResult】

  • 实例对象的另外一个属性 【promisereResult】,保存对象 【成功/失败】的结果
  • resolve
  • reject

promise 的基本流程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QtzpuOw9-1678617242972)(D:\01_Software\03-markdownImages\image-20230120105804528.png)]

为什么要用 Promise?

指定回调函数的方式更加灵活

  1. 旧的: 必须在启动异步任务前指定

  2. promise: 启动异步任务 => 返回promie对象 => 给promise对象绑定回调函

数(甚至可以在异步任务结束后指定/多个)

支持链式调用, 可以解决回调地狱问题

1、什么是回调地狱?

  • 回调函数嵌套调用, 外部回调函数异步执行的结果是嵌套的回调执行的条件

2、回调地狱的缺点?

  • 不便于阅读

  • 不便于异常处理

3、解决方案?

  • promise 链式调用

如果使用 Promise?

API

1、Promise 构造函数: Promise (excutor) {}

(1) executor 函数: 执行器 (resolve, reject) => {}

(2) resolve 函数: 内部定义成功时我们调用的函数 value => {}

(3) reject 函数: 内部定义失败时我们调用的函数 reason => {}

说明: executor 会在 Promise 内部立即同步调用,异步操作在执行器中执行

2、Promise.prototype.then 方法: (onResolved, onRejected) => {}

(1) onResolved 函数: 成功的回调函数 (value) => {}

(2) onRejected 函数: 失败的回调函数 (reason) => {}

说明: 指定用于得到成功 value 的成功回调和用于得到失败 reason 的失败回调

返回一个新的 promise 对象

3、 Promise.prototype.catch 方法: (onRejected) => {}

(1) onRejected 函数: 失败的回调函数 (reason) => {}

说明: then()的语法糖, 相当于: then(undefined, onRejected)

4、Promise.resolve 方法: (value) => {}

(1) value: 成功的数据或 promise 对象

说明: 返回一个成功/失败的 promise 对象

5、 Promise.reject 方法: (reason) => {}

(1) reason: 失败的原因

说明: 返回一个失败的 promise 对象

6、 Promise.all 方法: (promises) => {}

(1) promises: 包含 n 个 promise 的数组

说明: 返回一个新的 promise, 只有所有的 promise 都成功才成功, 只要有一个失败了就直接失败

let p1 = new Promise((resolve,reject) => {
    resolve("ok");
})
let p2 = new Promise('ok');
let p3 = new Promise('oh yeah');
const result = Promise.all([p1, p2, p3]);

7、 Promise.race 方法: (promises) => {}

(1) promises: 包含 n 个 promise 的数组

说明: 返回一个新的 promise, 第一个完成的 promise 的结果状态就是最终的结果状态

promise 的几个关键问题

1、 如何改变 promise 的状态?

(1) resolve(value): 如果当前是 pending 就会变为 resolved

(2) reject(reason): 如果当前是 pending 就会变为 rejected

(3) 抛出异常: 如果当前是 pending 就会变为 rejected

2、 一个 promise 指定多个成功/失败回调函数, 都会调用吗?

当 promise 改变为对应状态时都会调用

let p = new Promise((resolve, reject) => {
    resolve('ok');
})
p.then(value => {
    console.log("111");
})
p.then(value => {
    console.log("222");
})
//结果
ok
111
222

3、改变 promise 状态和指定回调函数谁先谁后?

(1) 都有可能, 正常情况下是先改变状态再指定回调, 但也可以先指定回调再修改状态

(2) 如何先改状态再指定回调?

​ ① 在执行器中直接调用 resolve()/reject()

​ ② 延迟更长时间才调用 then()

(3) 什么时候才能得到数据?

​ ① 如果先指定的回调, 那当状态发生改变时, 回调函数就会调用, 得到数据

​ ② 如果先改变的状态, 那当指定回调时, 回调函数就会调用, 得到数据

//1、同步任务,先改变状态后执行回调函数
let p1 = new Promise((resolve, reject) => {
    resolve('ok');
})
p.then(value => {
    console.log("111");
})
//2、同步任务,先指定回调函数后改变状态
let p2 = new Promise((resolve, reject) => {
    setInterval(() => {
        resolve('ok')
    }, 3000);
})
p.then(value => {
    console.log("111");
})

4、promise.then()返回的新 promise 的结果状态由什么决定?

(1) 简单表达: 由 then() 指定的回调函数执行的结果决定

(2) 详细表达:

​ ① 如果抛出异常, 新 promise 变为 rejected, reason 为抛出的异常

​ ② 如果返回的是非 promise 的任意值, 新 promise 变为 resolved,value 为返回的值

​ ③ 如果返回的是另一个新 promise, 此 promise 的结果就会成为新 promise 的结果

let p = new Promise((resolve, reflect) => {
            resolve('ok');
})
let result = p.then(value => {
            //1、抛出错误
            //console.log(value);
            //2、返回结果是非 Promise 类型的对象
            // return 321;
            //3、返回结果是 Promise 对象
            // return new Promise((resolve, reflect) => {
            //     resolve('seuccess');
            // })
}, reason => {

})
console.log(result);

5、 promise 如何串连多个操作任务?

(1) promise 的 then()返回一个新的 promise, 可以开成 then()的链式调用

(2) 通过 then 的链式调用串连多个同步/异步任务

let p = new Promise((resolve, reflect) => {
    resolve('ok');
})
p.then(value => {
    return new Promise((resolve, reflect) => {
        resolve("lasdkjflkdsajf");
    })
}).then(value => {
    console.log(value); // lasdkjflkdsajf
}).then(value => {
    console.log(value); // undefined
})

6、promise 异常传透?

(1) 当使用 promise 的 then 链式调用时, 可以在最后指定失败的回调,

(2) 前面任何操作出了异常, 都会传到最后失败的回调中处理

let p = new Promise((resolve, reflect) => {
    setTimeout(() => {
        resolve('ok');
    }, 1000)
})
p.then(value => {
    console.log("111");
}).then(value => {
    console.log("222");
}).then(value => {
    console.log("333");
}).catch(reason => {
    console.log(reason);
})
//结果
111
222
333

let p = new Promise((resolve, reflect) => {
    setTimeout(() => {
        resolve('ok');
    }, 1000)
})
p.then(value => {
    throw '错误啦';
}).then(value => {
    console.log("222");
}).then(value => {
    console.log("333");
}).catch(reason => {
    console.log(reason);
})
//结果
错误啦

7、中断 promise 链?

(1) 当使用 promise 的 then 链式调用时, 在中间中断, 不再调用后面的回调函数

(2) 办法: 在回调函数中返回一个 pendding 状态的 promise 对象

let p = new Promise((resolve, reflect) => {
    setTimeout(() => {
        resolve('ok');
    }, 1000)
})
p.then(value => {
    console.log("111");
    return new Promise(() => {})
}).then(value => {
    console.log("222");
}).then(value => {
    console.log("333");
}).catch(reason => {
    console.log(reason);
})
//结果
111

手写 Promise

前端

<script>
        //1、构建promise
        let promise = new minePromise((resolve, reflect) => {
            throw 'asdfsdaf';
        })

        //2、回调函数
        promise.then(value => {
            console.log(value);
        }, reason => {
            console.warn(reason);
        })
</script>

构造器函数

function minePromise(excutor) {
}

minePromise.prototype.then = function (onResolved, onRejected) {
}

resolve与reject

function minePromise(excutor) {
    this.promiseStatue = 'pedding';//promise状态
    this.promiseResult = null; // promise结果值
    const self = this;
    function resolve(data) {
		if (self.promiseStatue !== 'pedding') return;
        //1、修改 promise 的状态
        self.promiseStatue = 'fulfilled';
        //2、给 promiseResult 赋值
        self.promiseResult = data;
    }
    function reflect(data) {
		if (self.promiseStatue !== 'pedding') return;
        //1、修改 promise 的状态
        self.promiseStatue = 'reflected';
        //2、给 promiseResult 赋值
        self.promiseResult = data;
    }
    //捕抓异常
    excutor(resolve, reflect);

}

minePromise.prototype.then = function (onResolve, onReflect) {

}

throw 抛出异常

function minePromise(excutor) {
    this.promiseStatue = 'pedding';//promise状态
    this.promiseResult = null; // promise结果值
    const self = this;
    function resolve(data) {
        //1、修改 promise 的状态
        self.promiseStatue = 'fulfilled';
        //2、给 promiseResult 赋值
        self.promiseResult = data;
    }
    function reflect(data) {
        //1、修改  promise 的状态
        self.promiseStatue = 'rejected';
        //2、给 promiseResult 赋值
        self.promiseResult = data;
    }
    //捕抓异常
    try {
        excutor(resolve, reflect);
    } catch (error) {
        reflect(error);
    }
}

异步任务回调过程

function minePromise(excutor) {
    this.promiseStatue = 'peding';//promise状态
    this.promiseResult = null; // promise结果值
    this.callback = {};
    const self = this;
    function resolve(data) {
        if (self.promiseStatue !== 'peding') return;
        //1、修改 promise 的状态
        self.promiseStatue = 'fulfilled';
        //2、给 promiseResult 赋值
        self.promiseResult = data;
        if (self.callback.onResolved) {
            self.callback.onResolved(data);
        }
    }
    function reject(data) {
        if (self.promiseStatue !== 'peding') return;
        //1、修改  promise 的状态
        self.promiseStatue = 'rejected';
        //2、给 promiseResult 赋值
        self.promiseResult = data;
        if (self.callback.onRejected) {
            self.callback.onRejected(data);
        }
    }
    //捕抓异常
    try {
        excutor(resolve, reject);
    } catch (error) {
        reflect(error);
    }
}

minePromise.prototype.then = function (onResolved, onRejected) {
    if (this.promiseStatue === 'fulfilled') {
        onResolved(this.promiseResult);
    }
    if (this.promiseStatue === 'rejected') {
        onRejected(this.promiseResult);
    }

    //异步任务
    //1、将回调函数保存在变量中
    //2、等待promise改变状态时调用
    if (this.promiseStatue === 'peding') {
        this.callback = {
            onResolved: onResolved,
            onRejected: onRejected
        }
    }
}

多个任务回调

function minePromise(excutor) {
    this.promiseStatue = 'peding';//promise状态
    this.promiseResult = null; // promise结果值
    this.callbacks = [];
    const self = this;
    function resolve(data) {
        if (self.promiseStatue !== 'peding') return;
        //1、修改 promise 的状态
        self.promiseStatue = 'fulfilled';
        //2、给 promiseResult 赋值
        self.promiseResult = data;
        if (self.callbacks.length !== 0) {
            self.callbacks.forEach(item => {
                item.onResolved(data);
            })
        }
    }
    function reject(data) {
        if (self.promiseStatue !== 'peding') return;
        //1、修改  promise 的状态
        self.promiseStatue = 'rejected';
        //2、给 promiseResult 赋值
        self.promiseResult = data;
        if (self.callbacks.length !== 0) {
            self.callbacks.forEach(item => {
                item.onRejected(data);
            })
        }
    }
    //捕抓异常
    try {
        excutor(resolve, reject);
    } catch (error) {
        reflect(error);
    }
}

minePromise.prototype.then = function (onResolved, onRejected) {
    if (this.promiseStatue === 'fulfilled') {
        onResolved(this.promiseResult);
    }
    if (this.promiseStatue === 'rejected') {
        onRejected(this.promiseResult);
    }

    //异步任务
    //1、将回调函数保存在变量中
    //2、等待promise改变状态时调用
    if (this.promiseStatue === 'peding') {
        this.callbacks.push({
            onResolved: onResolved,
            onRejected: onRejected
        });
    }
}

then 返回结果

function minePromise(excutor) {
    this.promiseStatue = 'peding';//promise状态
    this.promiseResult = null; // promise结果值
    this.callbacks = [];
    const self = this;
    function resolve(data) {
        if (self.promiseStatue !== 'peding') return;
        //1、修改 promise 的状态
        self.promiseStatue = 'fulfilled';
        //2、给 promiseResult 赋值
        self.promiseResult = data;
        if (self.callbacks.length !== 0) {
            self.callbacks.forEach(item => {
                item.onResolved(data);
            })
        }
    }
    function reject(data) {
        if (self.promiseStatue !== 'peding') return;
        //1、修改  promise 的状态
        self.promiseStatue = 'rejected';
        //2、给 promiseResult 赋值
        self.promiseResult = data;
        if (self.callbacks.length !== 0) {
            self.callbacks.forEach(item => {
                item.onRejected(data);
            })
        }
    }
    //捕抓异常
    try {
        excutor(resolve, reject);
    } catch (error) {
        reject(error);
    }
}

minePromise.prototype.then = function (onResolved, onRejected) {
    return new minePromise((resolve, reject) => {
        if (this.promiseStatue === 'fulfilled') {
            try {
                // onResolved(this.promiseResult);
                let result = onResolved(this.promiseResult);
                //1、如果内部的promise是成功的则最终返回的就是成功的
                //2、反之就是失败的
                if (result instanceof minePromise) {
                    result.then(v => {
                        resolve(v);
                    }, r => {
                        reject(r);
                    });
                } else {
                    resolve(result);
                }
            } catch (e) {
                reject(e);
            }
        }
        if (this.promiseStatue === 'rejected') {
            onRejected(this.promiseResult);
        }

        //异步任务
        //1、将回调函数保存在变量中
        //2、等待promise改变状态时调用
        if (this.promiseStatue === 'peding') {
            this.callbacks.push({
                onResolved: onResolved,
                onRejected: onRejected
            });
        }
    });

}

异步修改then返回结果

function minePromise(excutor) {
    this.promiseStatue = 'peding';//promise状态
    this.promiseResult = null; // promise结果值
    this.callbacks = [];
    const self = this;
    function resolve(data) {
        if (self.promiseStatue !== 'peding') return;
        //1、修改 promise 的状态
        self.promiseStatue = 'fulfilled';
        //2、给 promiseResult 赋值
        self.promiseResult = data;
        if (self.callbacks.length !== 0) {
            self.callbacks.forEach(item => {
                item.onResolved(data);
            })
        }
    }
    function reject(data) {
        if (self.promiseStatue !== 'peding') return;
        //1、修改  promise 的状态
        self.promiseStatue = 'rejected';
        //2、给 promiseResult 赋值
        self.promiseResult = data;
        if (self.callbacks.length !== 0) {
            self.callbacks.forEach(item => {
                item.onRejected(data);
            })
        }
    }
    //捕抓异常
    try {
        excutor(resolve, reject);
    } catch (error) {
        reject(error);
    }
}

minePromise.prototype.then = function (onResolved, onRejected) {
    const self = this;

    return new minePromise((resolve, reject) => {

        //封装函数
        function temp(type) {
            try {
                // onResolved(this.promiseResult);
                let result = type(self.promiseResult);
                console.log(result);
                //1、如果内部的promise是成功的则最终返回的就是成功的
                //2、反之就是失败的
                if (result instanceof minePromise) {
                    result.then(v => {
                        resolve(v);
                    }, r => {
                        reject(r);
                    });
                } else {
                    resolve(result);
                }
            } catch (e) {
                reject(e);
            }
        }
        if (this.promiseStatue === 'fulfilled') {
            temp(onResolved);
        }

        if (this.promiseStatue === 'rejected') {
            temp(onRejected);
        }

        //异步任务
        //1、将回调函数保存在变量中
        //2、等待promise改变状态时调用
        if (this.promiseStatue === 'peding') {
            //指定多个回调函数
            //异步任务下的then返回的结果let
            //1、如果没有返回结果直接返回undefind 以及成功promise对象
            //2、如果有promise类型的返回结果则返回data以及相对应的promise对象
            this.callbacks.push({
                onResolved: function () {
                    temp(onResolved);
                },
                onRejected: function () {
                    temp(onRejected);
                }
            });
        }
    });

}

catch

function minePromise(excutor) {
    this.promiseStatue = 'peding';//promise状态
    this.promiseResult = null; // promise结果值
    this.callbacks = [];
    const self = this;
    function resolve(data) {
        if (self.promiseStatue !== 'peding') return;
        //1、修改 promise 的状态
        self.promiseStatue = 'fulfilled';
        //2、给 promiseResult 赋值
        self.promiseResult = data;
        if (self.callbacks.length !== 0) {
            self.callbacks.forEach(item => {
                item.onResolved(data);
            })
        }
    }
    function reject(data) {
        if (self.promiseStatue !== 'peding') return;
        //1、修改  promise 的状态
        self.promiseStatue = 'rejected';
        //2、给 promiseResult 赋值
        self.promiseResult = data;
        if (self.callbacks.length !== 0) {
            self.callbacks.forEach(item => {
                item.onRejected(data);
            })
        }
    }
    //捕抓异常
    try {
        excutor(resolve, reject);
    } catch (error) {
        reject(error);
    }
}

minePromise.prototype.then = function (onResolved, onRejected) {
    const self = this;
    //判断回调函数参数
    if (typeof onRejected !== 'function') {
        onRejected = reason => {
            throw reason;
        }
    }
    if (typeof onResolved !== 'function') {
        onResolved = value => value;
    }
    return new minePromise((resolve, reject) => {

        //封装函数
        function temp(type) {
            try {
                // onResolved(this.promiseResult);
                let result = type(self.promiseResult);

                //1、如果内部的promise是成功的则最终返回的就是成功的
                //2、反之就是失败的
                if (result instanceof minePromise) {
                    result.then(v => {
                        resolve(v);
                    }, r => {
                        reject(r);
                    });
                } else {
                    resolve(result);
                }
            } catch (e) {
                reject(e);
            }
        }
        if (this.promiseStatue === 'fulfilled') {
            temp(onResolved);
        }

        if (this.promiseStatue === 'rejected') {
            temp(onRejected);
        }

        //异步任务
        //1、将回调函数保存在变量中
        //2、等待promise改变状态时调用
        if (this.promiseStatue === 'peding') {
            //指定多个回调函数
            //异步任务下的then返回的结果let
            //1、如果没有返回结果直接返回undefind 以及成功promise对象
            //2、如果有promise类型的返回结果则返回data以及相对应的promise对象
            this.callbacks.push({
                onResolved: function () {
                    temp(onResolved);
                },
                onRejected: function () {
                    temp(onRejected);
                }
            });
        }
    });

}

minePromise.prototype.catch = function (onRejected) {
    return this.then(undefined, onRejected);
}

添加静态方法resolve/reject

//添加resolve方法
minePromise.resolve = function (value) {
    return new minePromise((resolve, reject) => {
        if (value instanceof minePromise) {
            value.then(value => {
                resolve(value);
            }, reason => {
                reject(reason);
            });
        } else {
            resolve(value);
        }
    });
}

//添加reject方法
minePromise.reject = function (reason) {
    return new minePromise((resolve, reject) => {
        reject(reason);
    })
}

All方法

function minePromise(excutor) {
    this.promiseStatue = 'peding';//promise状态
    this.promiseResult = null; // promise结果值
    this.callbacks = [];
    const self = this;
    function resolve(data) {
        if (self.promiseStatue !== 'peding') return;
        //1、修改 promise 的状态
        self.promiseStatue = 'fulfilled';
        //2、给 promiseResult 赋值
        self.promiseResult = data;
        if (self.callbacks.length !== 0) {
            self.callbacks.forEach(item => {
                item.onResolved(data);
            })
        }
    }
    function reject(data) {
        if (self.promiseStatue !== 'peding') return;
        //1、修改  promise 的状态
        self.promiseStatue = 'rejected';
        //2、给 promiseResult 赋值
        self.promiseResult = data;
        if (self.callbacks.length !== 0) {
            self.callbacks.forEach(item => {
                item.onRejected(data);
            })
        }
    }
    //捕抓异常
    try {
        excutor(resolve, reject);
    } catch (error) {
        reject(error);
    }
}

minePromise.prototype.then = function (onResolved, onRejected) {
    const self = this;
    //判断回调函数参数
    if (typeof onRejected !== 'function') {
        onRejected = reason => {
            throw reason;
        }
    }
    if (typeof onResolved !== 'function') {
        onResolved = value => value;
    }
    return new minePromise((resolve, reject) => {

        //封装函数
        function temp(type) {
            try {
                // onResolved(this.promiseResult);
                let result = type(self.promiseResult);

                //1、如果内部的promise是成功的则最终返回的就是成功的
                //2、反之就是失败的
                if (result instanceof minePromise) {
                    result.then(v => {
                        resolve(v);
                    }, r => {
                        reject(r);
                    });
                } else {
                    resolve(result);
                }
            } catch (e) {
                reject(e);
            }
        }
        if (this.promiseStatue === 'fulfilled') {
            temp(onResolved);
        }

        if (this.promiseStatue === 'rejected') {
            temp(onRejected);
        }

        //异步任务
        //1、将回调函数保存在变量中
        //2、等待promise改变状态时调用
        if (this.promiseStatue === 'peding') {
            //指定多个回调函数
            //异步任务下的then返回的结果let
            //1、如果没有返回结果直接返回undefind 以及成功promise对象
            //2、如果有promise类型的返回结果则返回data以及相对应的promise对象
            this.callbacks.push({
                onResolved: function () {
                    temp(onResolved);
                },
                onRejected: function () {
                    temp(onRejected);
                }
            });
        }
    });

}

minePromise.prototype.catch = function (onRejected) {
    return this.then(undefined, onRejected);
}

//添加resolve方法
minePromise.resolve = function (value) {
    return new minePromise((resolve, reject) => {
        if (value instanceof minePromise) {
            value.then(value => {
                resolve(value);
            }, reason => {
                reject(reason);
            });
        } else {
            resolve(value);
        }
    });
}

//添加reject方法
minePromise.reject = function (reason) {
    return new minePromise((resolve, reject) => {
        reject(reason);
    })
}

//添加all方法
minePromise.all = function (arr) {
    return new minePromise((resolve, reject) => {
        let count = 0;
        let temp = [];
        for (let i = 0; i < arr.length; i++) {

            arr[i].then(value => {
                count++;
                temp[i] = value;
                if (count === arr.length) {
                    resolve(temp);
                }
            }, reason => {
                reject(reason);
            });
        }
    })

}


Race 方法

minePromise.race = function (promises) {
    return new minePromise((resolve, reject) => {
        for (let i = 0; i < promises.length; i++) {
            promises[i].then(value => {
                resolve(value);
            }, reason => {
                reject(reason);
            })
        }
    })
}

class版本的实现

class Promise {
    //构造方法
    constructor(executor) {
        this.promiseStatue = 'peding';//promise状态
        this.promiseResult = null; // promise结果值
        this.callbacks = [];
        const self = this;
        function resolve(data) {
            if (self.promiseStatue !== 'peding') return;
            //1、修改 promise 的状态
            self.promiseStatue = 'fulfilled';
            //2、给 promiseResult 赋值
            self.promiseResult = data;
            if (self.callbacks.length !== 0) {
                self.callbacks.forEach(item => {
                    item.onResolved(data);
                })
            }
        }
        function reject(data) {
            if (self.promiseStatue !== 'peding') return;
            //1、修改  promise 的状态
            self.promiseStatue = 'rejected';
            //2、给 promiseResult 赋值
            self.promiseResult = data;
            if (self.callbacks.length !== 0) {
                self.callbacks.forEach(item => {
                    item.onRejected(data);
                })
            }
        }
        //捕抓异常
        try {
            excutor(resolve, reject);
        } catch (error) {
            reject(error);
        }
    }

    //then方法
    then(onResolved, onRejected) {
        const self = this;
        //判断回调函数参数
        if (typeof onRejected !== 'function') {
            onRejected = reason => {
                throw reason;
            }
        }
        if (typeof onResolved !== 'function') {
            onResolved = value => value;
        }
        return new Promise((resolve, reject) => {

            //封装函数
            function temp(type) {
                try {
                    // onResolved(this.promiseResult);
                    let result = type(self.promiseResult);

                    //1、如果内部的promise是成功的则最终返回的就是成功的
                    //2、反之就是失败的
                    if (result instanceof Promise) {
                        result.then(v => {
                            resolve(v);
                        }, r => {
                            reject(r);
                        });
                    } else {
                        resolve(result);
                    }
                } catch (e) {
                    reject(e);
                }
            }
            if (this.promiseStatue === 'fulfilled') {
                temp(onResolved);
            }

            if (this.promiseStatue === 'rejected') {
                temp(onRejected);
            }

            //异步任务
            //1、将回调函数保存在变量中
            //2、等待promise改变状态时调用
            if (this.promiseStatue === 'peding') {
                //指定多个回调函数
                //异步任务下的then返回的结果let
                //1、如果没有返回结果直接返回undefind 以及成功promise对象
                //2、如果有promise类型的返回结果则返回data以及相对应的promise对象
                this.callbacks.push({
                    onResolved: function () {
                        temp(onResolved);
                    },
                    onRejected: function () {
                        temp(onRejected);
                    }
                });
            }
        });
    }

    //catch方法
    catch(onRejected) {
        return this.then(undefined, onRejected);
    }
    //静态方法resolve
    static resolve() {
        return new Promise((resolve, reject) => {
            if (value instanceof Promise) {
                value.then(value => {
                    resolve(value);
                }, reason => {
                    reject(reason);
                });
            } else {
                resolve(value);
            }
        });
    }
    //静态方法reject
    static reject() {
        return new Promise((resolve, reject) => {
            reject(reason);
        })
    }

    //静态方法all
    static all(arr) {
        return new Promise((resolve, reject) => {
            let count = 0;
            let temp = [];
            for (let i = 0; i < arr.length; i++) {

                arr[i].then(value => {
                    count++;
                    temp[i] = value;
                    if (count === arr.length) {
                        resolve(temp);
                    }
                }, reason => {
                    reject(reason);
                });
            }
        })
    }

    //静态方法race
    static race(arr) {
        return new Promise((resolve, reject) => {
            for (let i = 0; i < promises.length; i++) {
                promises[i].then(value => {
                    resolve(value);
                }, reason => {
                    reject(reason);
                })
            }
        })
    }
}

asynv 与 await

1、async 函数

  1. 函数的返回值为 promise 对象,async 返回的是 promise 对象,其中规则是跟 then 函数一直。

  2. promise 对象的结果由 async 函数执行的返回值决定

async function main(){
    //1、如果返回值是一个非 Promise 类型的数据
    return asdf;
    //2、如果返回的是一个Promise对象
    return new Promise((resolve,reject)=>{
        reject('error');
    })
    //3、抛出异常
    throw 'oh no';
}
let result = main();
console.log(result);

2、await 表达式

  1. await 右侧的表达式一般为 promise 对象, 但也可以是其它的值

  2. 如果表达式是 promise 对象, await 返回的是 promise 成功的值

  3. 如果表达式是其它值, 直接将此值作为 await 的返回值

async function main(){
    let p = new Promise((resolve,reject)=>{
        //resolve('ok');
        reject("error");
    })
    //1、右侧为promise的情况
    let result1 = await p;
    //结果:20
    
    //2、右侧为其他类的数据
    let resutl2 = await 20;
    //结果:20
    
    //3、如果promise是失败的状态
    try{
        let res = await p;
    }catch(e){
        console.log(e);
        //结果:error
    }
}

注意事项

1、await 必须写在 async 函数中, 但 async 函数中可以没有 await

2、如果 await 的 promise 失败了, 就会抛出异常, 需要通过 try…catch 捕获处理

async 表达式与 await 结合

const fs = require('fs');
const util = require('util');
const mineReadFile = util.promisify(fs.readFile);
async function main(){
    try{
        let data1 = await mineReadfile('./resource/1.html');
        let data2 = await mineReadfile('./resource/2.html');
        let data3 = await mineReadfile('./resource/3.html');
        console.log(data1 + data2 + data3);
    }catch(e){
        console.log(e);
    }
}

async function main(){
//1、如果返回值是一个非 Promise 类型的数据
return asdf;
//2、如果返回的是一个Promise对象
return new Promise((resolve,reject)=>{
reject(‘error’);
})
//3、抛出异常
throw ‘oh no’;
}
let result = main();
console.log(result);


## 2、await 表达式

1. **await 右侧的表达式一般为 promise 对象, 但也可以是其它的值**

2. **如果表达式是 promise 对象, await 返回的是 promise 成功的值**

3. **如果表达式是其它值, 直接将此值作为 await 的返回值**

```js
async function main(){
    let p = new Promise((resolve,reject)=>{
        //resolve('ok');
        reject("error");
    })
    //1、右侧为promise的情况
    let result1 = await p;
    //结果:20
    
    //2、右侧为其他类的数据
    let resutl2 = await 20;
    //结果:20
    
    //3、如果promise是失败的状态
    try{
        let res = await p;
    }catch(e){
        console.log(e);
        //结果:error
    }
}

注意事项

1、await 必须写在 async 函数中, 但 async 函数中可以没有 await

2、如果 await 的 promise 失败了, 就会抛出异常, 需要通过 try…catch 捕获处理

async 表达式与 await 结合

const fs = require('fs');
const util = require('util');
const mineReadFile = util.promisify(fs.readFile);
async function main(){
    try{
        let data1 = await mineReadfile('./resource/1.html');
        let data2 = await mineReadfile('./resource/2.html');
        let data3 = await mineReadfile('./resource/3.html');
        console.log(data1 + data2 + data3);
    }catch(e){
        console.log(e);
    }
}
 类似资料: