1. Promise 的理解
MDN
是这样解释的:
一个 Promise
对象代表一个在这个 promise
被创建出来时不一定已知值的代理。它让你能够把异步操作最终的成功返回值或者失败原因和相应的处理程序关联起来。这样使得异步方法可以像同步方法那样返回值:异步方法并不会立即返回最终的值,而是会返回一个 promise
,以便在未来某个时候把值交给使用者。
一个 Promise
必然处于以下几种状态之一:
待定(pending
):初始状态,既没有被兑现,也没有被拒绝。
已兑现(fulfilled
):意味着操作成功完成。
已拒绝(rejected
):意味着操作失败。
有点拗口,通俗来讲就是:
所谓Promise
,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果
Promise
是一个构造函数,自己身上有all
、reject
、resolve
这几个方法,原型上有then、catch
等方法;promise
对象用来封装一个异步操作并可以获取其成功/失败的结果值
2. Promise的构成
let p = new Promise([executor])
new Promise()
括号内部必须是一个可执行函数new Promise
的时候,在Promise
内部会立即把[executor]
函数执行- 函数中一般用来管理一个异步编程代码,不管控异步编程也是可以的
- 同时给
[exector]
函数传递两个值:resolve、rejecct
3. Promise的基本使用
3.1 new Promise()是一个实例
let p1 = new Promise((resolve, reject) => {
});
console.log(p1);
打印p1结果
中括号[[]]
的属性叫内置属性:浏览器内部的属性,不能操作
p
是Promise
类的一个实例- 内置私有属性
[[PromiseState]] :
实例状态:pending、fulfilled/resolved、rejected
[[PromiseResult]]:
实例的值
- 公共属性方法 Promise.prototype
then
catch
finally
Symbol(Symbol.toStringTag)
,可以使用Object.prototype.toString.call(p1)
检测是否是promise
, 结果是"[object Promise]"
- 内置私有属性
注意: Promise是异步的,new Promise是同步的,会立即执行内部函数
3.1 promise修改状态
在[executor]
执行resolve/reject
都是为了改变promise
实例的状态和值(结果)
promise一旦状态被改变,则不能改变成其他状态
let p1 = new Promise((resolve, reject) => {
resolve("ok");
reject("no");
});
console.log(p1);
resolve
和reject
都执行,只会返回第一个状态(成功)/值,如果注释掉resolve
,则会返回失败状态/值,如下图
如果[executor]
函数报错,Promise
状态会变成rejected
,结果是报错原因,Promise
内部做了一场信息捕获try catch
let p1 = new Promise((resolve, reject) => {
// reject("no");
// resolve("ok");
console.log(a);
});
console.log(p1);
4. 为什么要用 Promise?
1. 指定回调函数的方式更加灵活
不用promise:必须在启动异步任务前指定
使用promise::启动异步任务 => 返回promie对象 => 给promise对象绑定回调函
数(甚至可以在异步任务结束后指定/多个
2. 支持链式调用, 可以解决回调地狱问题
- 什么是回调地狱?
回调函数嵌套调用, 外部回调函数异步执行的结果是嵌套的回调执行的条件 - 回调地狱的缺点?
不便于阅读, 不便于异常处理 - 解决方案?
promise
链式调用 - 终极解决方案
async/await
5. Promise API
1. Promise 构造函数: Promise (excutor) {}
executor
函数: 执行器(resolve, reject) => {}
resolve
函数: 内部定义成功时我们调用的函数value => {}
reject
函数: 内部定义失败时我们调用的函数reason => {}
说明: executor
会在 Promise
内部立即同步调用,异步操作在执行器中执行
2. Promise.prototype.then 方法: p.then(onResolved, onRejected)
onResolved
函数: 成功的回调函数(value) => {}
onRejected
函数: 失败的回调函数(reason) => {}
说明: 指定用于得到成功 value
的成功回调和用于得到失败 reason
的失败回调,返回一个新的 promise
对象
3. Promise.prototype.catch 方法:p.catch(onRejected)
onRejected
函数: 失败的回调函数(reason) => {}
说明: 这是then()的语法糖, 相当于:then(undefined/null, onRejected)
4. Promise.resolve 方法: Promise.resolve(value)
value
: 将被 Promise
对象解析的参数,也可以是一个成功或失败的Promise
对象
说明: 返回一个成功/失败的 promise 对象
-
如果传入的参数为 非Promise类型的对象, 则返回的结果为成功promise对象
let p1 = Promise.resolve(555); console.log(p1); // Promise {<fulfilled>: 555}
-
如果传入的参数为 Promise 对象, 则参数的结果决定了 resolve 的结果
let p2 = Promise.resolve(new Promise((resolve, reject) => { // resolve('OK'); // 成功的Promise reject('Error'); })); console.log(p2); p2.catch(reason => { console.log(reason); })
5. Promise.reject 方法: Promise.reject (reason)
reason: 失败的原因
说明:返回一个失败的 promise 对象
let p = Promise.reject(555);
let p2 = Promise.reject('hhh');
let p3 = Promise.reject(new Promise((resolve, reject) => {
resolve('OK');
}));
console.log(p);
console.log(p2);
console.log(p3);
Promise.resolve()/Promise.reject() 方法就是一个语法糖,用来快速得到Promise对象
//产生一个成功值为1的promise对象
new Promise((resolve, reject) => {
resolve(1)
})
//相当于
const p1 = Promise.resolve(1)
const p2 = Promise.resolve(2)
const p3 = Promise.reject(3)
p1.then(value => {
console.log(value)}) // 1
p2.then(value => {
console.log(value)}) // 2
p3.catch(reason => {
console.log(reason)}) // 3
6. Promise.all 方法: Promise.all(iterable)
iterable:包含 n 个 promise 的可迭代对象,如 Array 或 String
说明:返回一个新的 promise,只有所有的 promise 都成功才成功,只要有一个失败了就直接失败
获取promise返回的每个结果需要使用then
let p1 = new Promise((resolve, reject) => {
resolve('OK');
})
// let p2 = Promise.resolve('Success');
let p2 = Promise.reject('Error');
let p3 = Promise.resolve('Oh Yeah');
//
const result = Promise.all([p1, p2, p3]);
console.log(result);
result.then(data => {
console.log(data);
});
7. Promise.race方法:Promise.race(iterable)
iterable:包含 n 个 promise 的可迭代对象,如 Array 或 String
说明:返回一个新的 promise,第一个完成的 promise 的结果状态就是最终的结果状态
谁先完成就输出谁(不管是成功还是失败)
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK');
}, 1000);
})
let p2 = Promise.resolve('Success');
let p3 = Promise.resolve('Oh Yeah');
//调用
const result = Promise.race([p1, p2, p3]);
console.log(result);
6. promise 的几个关键问题
6.1 如何改变 promise 的状态?
- resolve(value): 如果当前是 pending 就会变为 resolved
- reject(reason): 如果当前是 pending 就会变为 rejected
- 抛出异常: 如果当前是 pending 就会变为 rejected
let p = new Promise((resolve, reject) => {
//1. resolve 函数
// resolve('ok'); // pending => fulfilled (resolved)
//2. reject 函数
// reject("error");// pending => rejected
//3. 抛出错误
// throw '出问题了';
});
console.log(p);
6.2 一个 promise 指定多个成功/失败回调函数, 都会调用吗?
当 promise 改变为对应状态时都会调用
let p = new Promise((resolve, reject) => {
resolve('OK');
});
///指定回调 - 1
p.then(value => {
console.log(value);
});
//指定回调 - 2
p.then(value => {
alert(value);
});
6.3 改变 promise 状态和指定回调函数谁先谁后?
都有可能, 一般是先指定回调再改变状态, 但也可以先改状态再指定回调
先改状态再指定回调:
- 在执行器中直接调用
resolve()/reject()
- 当指定回调时, 回调函数就会调用, 得到数据
先指定回调后改状态:
- 异步调用
resolve()/reject()
- 当状态发生改变时, 回调函数就会调用, 得到数据,总之,得到数据都在最后一步
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK');
}, 1000);
});
p.then(value => {
console.log(value);
},reason=>{
})
6.4 promise.then()返回的新 promise 的结果状态由什么决定?
- 如果抛出异常, 新 promise 变为 rejected, reason 为抛出的异常
- 如果返回的是非 promise 的任意值, 新 promise 变为 resolved, value 为返回的值
- 如果返回的是另一个新 promise, 此 promise 的结果就会成为新 promise 的结果
let p = new Promise((resolve, reject) => {
resolve('ok');
});
//执行 then 方法
let result = p.then(value => {
// console.log(value);
//1. 抛出错误
// throw '出了问题';
//2. 返回结果是非 Promise 类型的对象
// return 555;
//3. 返回结果是 Promise 对象
// return new Promise((resolve, reject) => {
// // resolve('success');
// reject('error');
// });
}, reason => {
console.warn(reason);
});
console.log(result);
6.5 promise 如何串连多个操作任务?
- promise 的 then()返回一个新的 promise, 可以开启 then()的链式调用
- 通过 then 的链式调用串连多个同步/异步任务
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK');
}, 1000);
});
p.then(value => {
return new Promise((resolve, reject) => {
resolve("success");
});
}).then(value => {
console.log(value); // success
}).then(value => {
console.log(value); // undefined 上一个then没有返回
})
6.6 promise的异常穿透
- 当使用 promise 的 then 链式调用时, 可以在最后指定失败的回调
- 前面任何操作出了异常, 都会传到最后失败的回调中处理
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK');
// reject('Err');
}, 1000);
});
p.then(value => {
// console.log(111);
throw '失败啦!';
}).then(value => {
console.log(222);
}).then(value => {
console.log(333);
}).catch(reason => {
console.warn(reason);
});
6.7 中断 promise 链?
当使用 promise 的 then 链式调用时, 在中间中断, 不再调用后面的回调函数
办法: 在回调函数中返回一个 pendding 状态的 promise 对象
let p = new Promise((resolve, reject) => {
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.warn(reason);
});
7. 手写promise
<script src="./promise.js"></script>
let p = new Promise((resolve, reject) => {
resolve('OK');
});
p.then(value => {
console.log(value);
}, reason=>{
console.warn(reason);
})
7.1 定义整体结构
function Promise(executor){
}
//添加 then 方法
Promise.prototype.then = function(onResolved, onRejected){
}
7.2 resolve和reject结构搭建
//声明构造函数
function Promise(executor){
//resolve 函数
function resolve(data){
}
//reject 函数
function reject(data){
}
//同步调用『执行器函数』
executor(resolve, reject); //需要定义resolve和reject
}
//添加 then 方法
Promise.prototype.then = function(onResolved, onRejected){
}
7.3 resolve和reject的代码实现
我们知道resolve、reject就做了两件事: 改变状态、设置结果值
//声明构造函数
function Promise(executor){
//添加属性
this.PromiseState = 'pending';
this.PromiseResult = null;
//保存实例对象的 this 的值
const self = this;// self _this that
//resolve 函数
function resolve(data){
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'fulfilled';// resolved
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
}
//reject 函数
function reject(data){
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'rejected';//
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
}
//同步调用『执行器函数』
executor(resolve, reject);
}
//添加 then 方法
Promise.prototype.then = function(onResolved, onRejected){
}
7.4 throw抛出异常改变状态
改变状态有三种方式:resolve、reject、throw
在执行器函数处调用了reject,所以try catch需要加到executor处
//声明构造函数
function Promise(executor){
//添加属性
this.PromiseState = 'pending';
this.PromiseResult = null;
//保存实例对象的 this 的值
const self = this;// self _this that
//resolve 函数
function resolve(data){
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'fulfilled';// resolved
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
}
//reject 函数
function reject(data){
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'rejected';//
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
}
try{
//同步调用『执行器函数』
executor(resolve, reject);
}catch(e){
//修改 promise 对象状态为『失败』
reject(e);
}
}
//添加 then 方法
Promise.prototype.then = function(onResolved, onRejected){
}
7.5 状态只能修改一次
判断状态 if(self.PromiseState !== 'pending') return;
//声明构造函数
function Promise(executor){
//添加属性
this.PromiseState = 'pending';
this.PromiseResult = null;
//保存实例对象的 this 的值
const self = this;// self _this that
//resolve 函数
function resolve(data){
//判断状态
if(self.PromiseState !== 'pending') return;
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'fulfilled';// resolved
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
}
//reject 函数
function reject(data){
//判断状态
if(self.PromiseState !== 'pending') return;
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'rejected';//
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
}
try{
//同步调用『执行器函数』
executor(resolve, reject);
}catch(e){
//修改 promise 对象状态为『失败』
reject(e);
}
}
//添加 then 方法
Promise.prototype.then = function(onResolved, onRejected){
}
7.6 then方法执行回调
//调用回调函数 PromiseState
if(this.PromiseState === 'fulfilled'){
onResolved(this.PromiseResult);
}
if(this.PromiseState === 'rejected'){
onRejected(this.PromiseResult);
}
//声明构造函数
function Promise(executor){
//添加属性
this.PromiseState = 'pending';
this.PromiseResult = null;
//保存实例对象的 this 的值
const self = this;// self _this that
//resolve 函数
function resolve(data){
//判断状态
if(self.PromiseState !== 'pending') return;
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'fulfilled';// resolved
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
}
//reject 函数
function reject(data){
//判断状态
if(self.PromiseState !== 'pending') return;
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'rejected';//
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
}
try{
//同步调用『执行器函数』
executor(resolve, reject);
}catch(e){
//修改 promise 对象状态为『失败』
reject(e);
}
}
//添加 then 方法
Promise.prototype.then = function(onResolved, onRejected){
//调用回调函数 PromiseState
if(this.PromiseState === 'fulfilled'){
onResolved(this.PromiseResult);
}
if(this.PromiseState === 'rejected'){
onRejected(this.PromiseResult);
}
}
7.7 异步任务回调的执行
//实例化对象
let p = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve('OK');
reject("error");
}, 1000);
});
p.then(value => {
console.log(value);
}, reason=>{
console.warn(reason);
});
console.log(p);
异步调用 得等到状态更改之后执行回调,所以在resolve/reject函数中执行回调,在then方法中添加回调函数
//声明构造函数
function Promise(executor){
//添加属性
this.PromiseState = 'pending';
this.PromiseResult = null;
//声明属性
this.callback = {
};
//保存实例对象的 this 的值
const self = this;// self _this that
//resolve 函数
function resolve(data){
//判断状态
if(self.PromiseState !== 'pending') return;
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'fulfilled';// resolved
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
//调用成功的回调函数
if(self.callback.onResolved){
self.callback.onResolved(data);
}
}
//reject 函数
function reject(data){
//判断状态
if(self.PromiseState !== 'pending') return;
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'rejected';//
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
//执行回调
if(self.callback.onResolved){
self.callback.onResolved(data);
}
}
try{
//同步调用『执行器函数』
executor(resolve, reject);
}catch(e){
//修改 promise 对象状态为『失败』
reject(e);
}
}
//添加 then 方法
Promise.prototype.then = function(onResolved, onRejected){
//调用回调函数 PromiseState
if(this.PromiseState === 'fulfilled'){
onResolved(this.PromiseResult);
}
if(this.PromiseState === 'rejected'){
onRejected(this.PromiseResult);
}
//判断 pending 状态
if(this.PromiseState === 'pending'){
//保存回调函数
this.callback = {
onResolved: onResolved,
onRejected: onRejected
}
}
}
7.8 指定多个回调的实现
//实例化对象
let p = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve('OK');
reject('No');
}, 1000);
});
p.then(value => {
console.log(value);
}, reason=>{
console.warn(reason);
});
p.then(value => {
alert(value);
}, reason=>{
alert(reason);
});
console.log(p);
如果只有一个then的话,可以把回调函数存为一个对象,但是promise要实现then的链式调用,就需要用数组存贮回调函数,这样每一个then里的回调函数都会执行
//声明构造函数
function Promise(executor){
//添加属性
this.PromiseState = 'pending';
this.PromiseResult = null;
//声明属性
this.callbacks = [];
//保存实例对象的 this 的值
const self = this;// self _this that
//resolve 函数
function resolve(data){
//判断状态
if(self.PromiseState !== 'pending') return;
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'fulfilled';// resolved
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
//调用成功的回调函数
self.callbacks.forEach(item => {
item.onResolved(data);
});
}
//reject 函数
function reject(data){
//判断状态
if(self.PromiseState !== 'pending') return;
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'rejected';//
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
//执行失败的回调
self.callbacks.forEach(item => {
item.onRejected(data);
});
}
try{
//同步调用『执行器函数』
executor(resolve, reject);
}catch(e){
//修改 promise 对象状态为『失败』
reject(e);
}
}
//添加 then 方法
Promise.prototype.then = function(onResolved, onRejected){
//调用回调函数 PromiseState
if(this.PromiseState === 'fulfilled'){
onResolved(this.PromiseResult);
}
if(this.PromiseState === 'rejected'){
onRejected(this.PromiseResult);
}
//判断 pending 状态
if(this.PromiseState === 'pending'){
//保存回调函数
this.callbacks.push({
onResolved: onResolved,
onRejected: onRejected
});
}
}
7.9 同步修改状态then方法返回结果
then方法的返回结果是一个promise对象
//声明构造函数
function Promise(executor){
//添加属性
this.PromiseState = 'pending';
this.PromiseResult = null;
//声明属性
this.callbacks = [];
//保存实例对象的 this 的值
const self = this;// self _this that
//resolve 函数
function resolve(data){
//判断状态
if(self.PromiseState !== 'pending') return;
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'fulfilled';// resolved
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
//调用成功的回调函数
self.callbacks.forEach(item => {
item.onResolved(data);
});
}
//reject 函数
function reject(data){
//判断状态
if(self.PromiseState !== 'pending') return;
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'rejected';//
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
//执行失败的回调
self.callbacks.forEach(item => {
item.onRejected(data);
});
}
try{
//同步调用『执行器函数』
executor(resolve, reject);
}catch(e){
//修改 promise 对象状态为『失败』
reject(e);
}
}
//添加 then 方法
Promise.prototype.then = function(onResolved, onRejected){
return new Promise((resolve, reject) => {
//调用回调函数 PromiseState
if(this.PromiseState === 'fulfilled'){
try{
//获取回调函数的执行结果
let result = onResolved(this.PromiseResult);
//判断
if(result instanceof Promise){
//如果是 Promise 类型的对象
result.then(v => {
resolve(v);
}, r=>{
reject(r);
})
}else{
//结果的对象状态为『成功』
resolve(result);
}
}catch(e){
reject(e);
}
}
if(this.PromiseState === 'rejected'){
onRejected(this.PromiseResult);
}
//判断 pending 状态
if(this.PromiseState === 'pending'){
//保存回调函数
this.callbacks.push({
onResolved: onResolved,
onRejected: onRejected
});
}
})
}
7.10 异步修改状态then方法返回结果
//声明构造函数
function Promise(executor){
//添加属性
this.PromiseState = 'pending';
this.PromiseResult = null;
//声明属性
this.callbacks = [];
//保存实例对象的 this 的值
const self = this;// self _this that
//resolve 函数
function resolve(data){
//判断状态
if(self.PromiseState !== 'pending') return;
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'fulfilled';// resolved
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
//调用成功的回调函数
self.callbacks.forEach(item => {
item.onResolved(data);
});
}
//reject 函数
function reject(data){
//判断状态
if(self.PromiseState !== 'pending') return;
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'rejected';//
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
//执行失败的回调
self.callbacks.forEach(item => {
item.onRejected(data);
});
}
try{
//同步调用『执行器函数』
executor(resolve, reject);
}catch(e){
//修改 promise 对象状态为『失败』
reject(e);
}
}
//添加 then 方法
Promise.prototype.then = function(onResolved, onRejected){
const self = this;
return new Promise((resolve, reject) => {
//调用回调函数 PromiseState
if(this.PromiseState === 'fulfilled'){
try{
//获取回调函数的执行结果
let result = onResolved(this.PromiseResult);
//判断
if(result instanceof Promise){
//如果是 Promise 类型的对象
result.then(v => {
resolve(v);
}, r=>{
reject(r);
})
}else{
//结果的对象状态为『成功』
resolve(result);
}
}catch(e){
reject(e);
}
}
if(this.PromiseState === 'rejected'){
onRejected(this.PromiseResult);
}
//判断 pending 状态
if(this.PromiseState === 'pending'){
//保存回调函数
this.callbacks.push({
onResolved: function(){
try{
//执行成功回调函数
let result = onResolved(self.PromiseResult);
//判断
if(result instanceof Promise){
result.then(v => {
resolve(v);
}, r=>{
reject(r);
})
}else{
resolve(result);
}
}catch(e){
reject(e);
}
},
onRejected: function(){
try{
//执行成功回调函数
let result = onRejected(self.PromiseResult);
//判断
if(result instanceof Promise){
result.then(v => {
resolve(v);
}, r=>{
reject(r);
})
}else{
resolve(result);
}
}catch(e){
reject(e);
}
}
});
}
})
}
7.11 then方法优化 封装callback
//声明构造函数
function Promise(executor){
//添加属性
this.PromiseState = 'pending';
this.PromiseResult = null;
//声明属性
this.callbacks = [];
//保存实例对象的 this 的值
const self = this;// self _this that
//resolve 函数
function resolve(data){
//判断状态
if(self.PromiseState !== 'pending') return;
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'fulfilled';// resolved
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
//调用成功的回调函数
self.callbacks.forEach(item => {
item.onResolved(data);
});
}
//reject 函数
function reject(data){
//判断状态
if(self.PromiseState !== 'pending') return;
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'rejected';//
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
//执行失败的回调
self.callbacks.forEach(item => {
item.onRejected(data);
});
}
try{
//同步调用『执行器函数』
executor(resolve, reject);
}catch(e){
//修改 promise 对象状态为『失败』
reject(e);
}
}
//添加 then 方法
Promise.prototype.then = function(onResolved, onRejected){
const self = this;
return new Promise((resolve, reject) => {
//封装函数
function callback(type){
try{
//获取回调函数的执行结果
let result = type(self.PromiseResult);
//判断
if(result instanceof Promise){
//如果是 Promise 类型的对象
result.then(v => {
resolve(v);
}, r=>{
reject(r);
})
}else{
//结果的对象状态为『成功』
resolve(result);
}
}catch(e){
reject(e);
}
}
//调用回调函数 PromiseState
if(this.PromiseState === 'fulfilled'){
callback(onResolved);
}
if(this.PromiseState === 'rejected'){
callback(onRejected);
}
//判断 pending 状态
if(this.PromiseState === 'pending'){
//保存回调函数
this.callbacks.push({
onResolved: function(){
callback(onResolved);
},
onRejected: function(){
callback(onRejected);
}
});
}
})
}
7.12 catch方法 异常穿透与值传递
//实例化对象
let p = new Promise((resolve, reject) => {
setTimeout(() => {
// reject('OK');
resolve('OK');
}, 1000);
});
//值传递
p.then()
.then(value=>{
console.log(222);
}).then(value => {
console.log(333);
}).catch(reason => {
console.warn(reason);
});
添加catch方法,并且需要判断回调函数的第一个和第二个参数是否存在
//判断回调函数参数
if(typeof onRejected !== 'function'){
onRejected = reason => {
throw reason;
}
}
if(typeof onResolved !== 'function'){
onResolved = value => value;
//value => { return value};
}
//声明构造函数
function Promise(executor){
//添加属性
this.PromiseState = 'pending';
this.PromiseResult = null;
//声明属性
this.callbacks = [];
//保存实例对象的 this 的值
const self = this;// self _this that
//resolve 函数
function resolve(data){
//判断状态
if(self.PromiseState !== 'pending') return;
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'fulfilled';// resolved
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
//调用成功的回调函数
self.callbacks.forEach(item => {
item.onResolved(data);
});
}
//reject 函数
function reject(data){
//判断状态
if(self.PromiseState !== 'pending') return;
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'rejected';//
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
//执行失败的回调
self.callbacks.forEach(item => {
item.onRejected(data);
});
}
try{
//同步调用『执行器函数』
executor(resolve, reject);
}catch(e){
//修改 promise 对象状态为『失败』
reject(e);
}
}
//添加 then 方法
Promise.prototype.then = function(onResolved, onRejected){
const self = this;
//判断回调函数参数
if(typeof onRejected !== 'function'){
onRejected = reason => {
throw reason;
}
}
if(typeof onResolved !== 'function'){
onResolved = value => value;
//value => { return value};
}
return new Promise((resolve, reject) => {
//封装函数
function callback(type){
try{
//获取回调函数的执行结果
let result = type(self.PromiseResult);
//判断
if(result instanceof Promise){
//如果是 Promise 类型的对象
result.then(v => {
resolve(v);
}, r=>{
reject(r);
})
}else{
//结果的对象状态为『成功』
resolve(result);
}
}catch(e){
reject(e);
}
}
//调用回调函数 PromiseState
if(this.PromiseState === 'fulfilled'){
callback(onResolved);
}
if(this.PromiseState === 'rejected'){
callback(onRejected);
}
//判断 pending 状态
if(this.PromiseState === 'pending'){
//保存回调函数
this.callbacks.push({
onResolved: function(){
callback(onResolved);
},
onRejected: function(){
callback(onRejected);
}
});
}
})
}
//添加 catch 方法
Promise.prototype.catch = function(onRejected){
return this.then(undefined, onRejected);
}
7.13 resolve方法封装
const p = Promise.resolve('OK');
const p2 = Promise.resolve(new Promise((resolve, reject) => {
// resolve('Success');
reject("error");
}));
const p3 = Promise.resolve(Promise.resolve('Oh Yeah'));
console.log(p3);
添加resolve方法,注意resolve是Promise这个函数的,不是实例对象的方法
//添加 resolve 方法
Promise.resolve = function(value){
//返回promise对象
return new Promise((resolve, reject) => {
if(value instanceof Promise){
value.then(v=>{
resolve(v);
}, r=>{
reject(r);
})
}else{
//状态设置为成功
resolve(value);
}
});
}
//声明构造函数
function Promise(executor){
//添加属性
this.PromiseState = 'pending';
this.PromiseResult = null;
//声明属性
this.callbacks = [];
//保存实例对象的 this 的值
const self = this;// self _this that
//resolve 函数
function resolve(data){
//判断状态
if(self.PromiseState !== 'pending') return;
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'fulfilled';// resolved
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
//调用成功的回调函数
self.callbacks.forEach(item => {
item.onResolved(data);
});
}
//reject 函数
function reject(data){
//判断状态
if(self.PromiseState !== 'pending') return;
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'rejected';//
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
//执行失败的回调
self.callbacks.forEach(item => {
item.onRejected(data);
});
}
try{
//同步调用『执行器函数』
executor(resolve, reject);
}catch(e){
//修改 promise 对象状态为『失败』
reject(e);
}
}
7.14 reject方法封装
//添加 reject 方法
Promise.reject = function(reason){
return new Promise((resolve, reject)=>{
reject(reason);
});
}
7.15 all方法封装
//添加 all 方法
Promise.all = function(promises){
//返回结果为promise对象
return new Promise((resolve, reject) => {
//声明变量
let count = 0;
let arr = [];
//遍历
for(let i=0;i<promises.length;i++){
//
promises[i].then(v => {
//得知对象的状态是成功
//每个promise对象 都成功
count++;
//将当前promise对象成功的结果 存入到数组中
arr[i] = v;
//判断
if(count === promises.length){
//修改状态
resolve(arr);
}
}, r => {
reject(r);
});
}
});
}
7.16 race方法封装
//添加 race 方法
Promise.race = function(promises){
return new Promise((resolve, reject) => {
for(let i=0;i<promises.length;i++){
promises[i].then(v => {
//修改返回对象的状态为 『成功』
resolve(v);
},r=>{
//修改返回对象的状态为 『失败』
reject(r);
})
}
});
}
7.15 then方法回调的异步执行的实现
let p1 = new Promise((resolve, reject) => {
reject('OK');
console.log(111);
});
p1.then(value => {
console.log(222);
}, reason => {
console.log(444);
});
console.log(333);
打印结果: 111 333 444
如果要实现,需要添加宏任务setTimeOut
//声明构造函数
function Promise(executor){
//添加属性
this.PromiseState = 'pending';
this.PromiseResult = null;
//声明属性
this.callbacks = [];
//保存实例对象的 this 的值
const self = this;// self _this that
//resolve 函数
function resolve(data){
//判断状态
if(self.PromiseState !== 'pending') return;
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'fulfilled';// resolved
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
//调用成功的回调函数
setTimeout(() => {
self.callbacks.forEach(item => {
item.onResolved(data);
});
});
}
//reject 函数
function reject(data){
//判断状态
if(self.PromiseState !== 'pending') return;
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'rejected';//
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
//执行失败的回调
setTimeout(() => {
self.callbacks.forEach(item => {
item.onRejected(data);
});
});
}
try{
//同步调用『执行器函数』
executor(resolve, reject);
}catch(e){
//修改 promise 对象状态为『失败』
reject(e);
}
}
//添加 then 方法
Promise.prototype.then = function(onResolved, onRejected){
const self = this;
//判断回调函数参数
if(typeof onRejected !== 'function'){
onRejected = reason => {
throw reason;
}
}
if(typeof onResolved !== 'function'){
onResolved = value => value;
//value => { return value};
}
return new Promise((resolve, reject) => {
//封装函数
function callback(type){
try{
//获取回调函数的执行结果
let result = type(self.PromiseResult);
//判断
if(result instanceof Promise){
//如果是 Promise 类型的对象
result.then(v => {
resolve(v);
}, r=>{
reject(r);
})
}else{
//结果的对象状态为『成功』
resolve(result);
}
}catch(e){
reject(e);
}
}
//调用回调函数 PromiseState
if(this.PromiseState === 'fulfilled'){
setTimeout(() => {
callback(onResolved);
});
}
if(this.PromiseState === 'rejected'){
setTimeout(() => {
callback(onRejected);
});
}
//判断 pending 状态
if(this.PromiseState === 'pending'){
//保存回调函数
this.callbacks.push({
onResolved: function(){
callback(onResolved);
},
onRejected: function(){
callback(onRejected);
}
});
}
})
}
//添加 catch 方法
Promise.prototype.catch = function(onRejected){
return this.then(undefined, onRejected);
}
//添加 resolve 方法
Promise.resolve = function(value){
//返回promise对象
return new Promise((resolve, reject) => {
if(value instanceof Promise){
value.then(v=>{
resolve(v);
}, r=>{
reject(r);
})
}else{
//状态设置为成功
resolve(value);
}
});
}
//添加 reject 方法
Promise.reject = function(reason){
return new Promise((resolve, reject)=>{
reject(reason);
});
}
//添加 all 方法
Promise.all = function(promises){
//返回结果为promise对象
return new Promise((resolve, reject) => {
//声明变量
let count = 0;
let arr = [];
//遍历
for(let i=0;i<promises.length;i++){
//
promises[i].then(v => {
//得知对象的状态是成功
//每个promise对象 都成功
count++;
//将当前promise对象成功的结果 存入到数组中
arr[i] = v;
//判断
if(count === promises.length){
//修改状态
resolve(arr);
}
}, r => {
reject(r);
});
}
});
}
//添加 race 方法
Promise.race = function(promises){
return new Promise((resolve, reject) => {
for(let i=0;i<promises.length;i++){
promises[i].then(v => {
//修改返回对象的状态为 『成功』
resolve(v);
},r=>{
//修改返回对象的状态为 『失败』
reject(r);
})
}
});
}
7.16 class版本的实现
class Promise{
//构造方法
constructor(executor){
//添加属性
this.PromiseState = 'pending';
this.PromiseResult = null;
//声明属性
this.callbacks = [];
//保存实例对象的 this 的值
const self = this;// self _this that
//resolve 函数
function resolve(data){
//判断状态
if(self.PromiseState !== 'pending') return;
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'fulfilled';// resolved
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
//调用成功的回调函数
setTimeout(() => {
self.callbacks.forEach(item => {
item.onResolved(data);
});
});
}
//reject 函数
function reject(data){
//判断状态
if(self.PromiseState !== 'pending') return;
//1. 修改对象的状态 (promiseState)
self.PromiseState = 'rejected';//
//2. 设置对象结果值 (promiseResult)
self.PromiseResult = data;
//执行失败的回调
setTimeout(() => {
self.callbacks.forEach(item => {
item.onRejected(data);
});
});
}
try{
//同步调用『执行器函数』
executor(resolve, reject);
}catch(e){
//修改 promise 对象状态为『失败』
reject(e);
}
}
//then 方法封装
then(onResolved,onRejected){
const self = this;
//判断回调函数参数
if(typeof onRejected !== 'function'){
onRejected = reason => {
throw reason;
}
}
if(typeof onResolved !== 'function'){
onResolved = value => value;
//value => { return value};
}
return new Promise((resolve, reject) => {
//封装函数
function callback(type){
try{
//获取回调函数的执行结果
let result = type(self.PromiseResult);
//判断
if(result instanceof Promise){
//如果是 Promise 类型的对象
result.then(v => {
resolve(v);
}, r=>{
reject(r);
})
}else{
//结果的对象状态为『成功』
resolve(result);
}
}catch(e){
reject(e);
}
}
//调用回调函数 PromiseState
if(this.PromiseState === 'fulfilled'){
setTimeout(() => {
callback(onResolved);
});
}
if(this.PromiseState === 'rejected'){
setTimeout(() => {
callback(onRejected);
});
}
//判断 pending 状态
if(this.PromiseState === 'pending'){
//保存回调函数
this.callbacks.push({
onResolved: function(){
callback(onResolved);
},
onRejected: function(){
callback(onRejected);
}
});
}
})
}
//catch 方法
catch(onRejected){
return this.then(undefined, onRejected);
}
//添加 resolve 方法
static resolve(value){
//返回promise对象
return new Promise((resolve, reject) => {
if(value instanceof Promise){
value.then(v=>{
resolve(v);
}, r=>{
reject(r);
})
}else{
//状态设置为成功
resolve(value);
}
});
}
//添加 reject 方法
static reject(reason){
return new Promise((resolve, reject)=>{
reject(reason);
});
}
//添加 all 方法
static all(promises){
//返回结果为promise对象
return new Promise((resolve, reject) => {
//声明变量
let count = 0;
let arr = [];
//遍历
for(let i=0;i<promises.length;i++){
//
promises[i].then(v => {
//得知对象的状态是成功
//每个promise对象 都成功
count++;
//将当前promise对象成功的结果 存入到数组中
arr[i] = v;
//判断
if(count === promises.length){
//修改状态
resolve(arr);
}
}, r => {
reject(r);
});
}
});
}
//添加 race 方法
static race (promises){
return new Promise((resolve, reject) => {
for(let i=0;i<promises.length;i++){
promises[i].then(v => {
//修改返回对象的状态为 『成功』
resolve(v);
},r=>{
//修改返回对象的状态为 『失败』
reject(r);
})
}
});
}
}
8. async 与 await
8.1 async 函数
- 函数的返回值为 promise 对象
- promise 对象的结果由 async 函数执行的返回值决定
同then
async function main(){
//1. 如果返回值是一个非Promise类型的数据
// return 521; //返回成功的promise对象状态
//2. 如果返回的是一个Promise对象
// return new Promise((resolve, reject) => {
// // resolve('OK');
// reject('Error');
// });
//3. 抛出异常
throw "Oh NO"; //返回失败的promise对象状态
}
let result = main();
console.log(result);
8.2 await表达式
- await 右侧的表达式一般为 promise 对象, 但也可以是其它的值
- 如果表达式是 promise 对象, await 返回的是 promise 成功的值
- 如果表达式是其它值, 直接将此值作为 await 的返回值
注意:
- await 必须写在 async 函数中, 但 async 函数中可以没有 await
- 如果 await 的 promise 失败了, 就会抛出异常, 需要通过 try…catch 捕获处理
async function main(){
let p = new Promise((resolve, reject) => {
// resolve('OK');
reject('Error');
})
//1. 右侧为promise的情况(成功状态)
// let res = await p; //ok
//2. 右侧为其他类型的数据
// let res2 = await 20; //20
//3. 如果promise是失败的状态
try{
let res3 = await p;
}catch(e){
console.log(e);
}
}
main();
8.3 async await与回调函数的区别
/**
* resource 1.html 2.html 3.html 文件内容
*/
const fs = require('fs');
const util = require('util');
const mineReadFile = util.promisify(fs.readFile);
//回调函数的方式
// fs.readFile('./resource/1.html', (err, data1) => {
// if(err) throw err;
// fs.readFile('./resource/2.html', (err, data2) => {
// if(err) throw err;
// fs.readFile('./resource/3.html', (err, data3) => {
// if(err) throw err;
// console.log(data1 + data2 + data3);
// });
// });
// });
//async 与 await
async function main(){
try{
//读取第一个文件的内容
let data1 = await mineReadFile('./resource/1x.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.code);
}
}
main();
参考https://www.bilibili.com/video/BV1GA411x7z1?p=1&vd_source=22466a8965f1e428d0c89e9b93d6d6b1