Promise 的简单用法。
- new Promise() 必须有回调函数。不然报错。
- 回调函数有两个参数分别是两个函数。一个是成功(resolve) 一个是失败。(reject)
- 这两个方法必须执行一个方法一般用于等待请求数据。
- 成功和失败我们都可以用then()来接收。then()有两个参数。都是函数。一个是接收成功的一个是接收失败的, 成功失败只能执行一个。
- 我们也可以用catch()放在then()后面调用。可以catch掉所有错误。
- then的第二个参数只能接收当前这个Promise的错误。 而catch()可以接收所有错误参数。
- then里面可以return Promise 也可以return 任意参数。都可以在下一个then()里面接收到。
const promise = new Promise(function(resolve, reject) {
resolve('成功');
})
promise.then((res) => {
console.log(res, 1111)
return '2222'
}).then((e) => {
console.log(e, 9999)
})
console.log(promise, 999);
Promise 静态方法
// 注定失败
Promise.reject('失败').catch((e) => {
console.log(1)
})
// 注定成功
Promise.resolve('成功').then((e) => {
console.log(2)
})
// 所有成功才成功
Promise.all([Promise.reject('失败'), Promise.resolve('成功')]).then(() => {
console.log(3)
}).catch((err) => {
console.log(err, 4)
})
// 谁先返回成功就成功
Promise.race([Promise.resolve('1111'), Promise.reject('失败')]).then(() => {
console.log(5)
}).catch((err) => {
console.log(err, 6)
})
模拟Promise 源码
/**
* 1. Promise 就是一个类, 在执行这个类的时候, 需要传递一个执行器进去 执行器会立即执行。
* 2. Promise 中有三种状态 分别是成功 fulfilled 失败 rejected 等待 pending
* 3. pending -> fulfilled
* 4. pending -> rejected
* 一旦状态确定就不可更改。
* 5.resolve 和 reject 函数是用来更改状态的
* resolve : fulfilled
* reject : rejected
* 调用then方法,有两个参数一个是成功之后的回调 ,一个是失败之后的回调。
* 因为成功和失败只有一个会执行 。
* */
// 创建一个类。
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJSCTED = 'rejected';
class MyPromise {
// 构造器参数接收调用者传来的函数
constructor (excutor) {
// 函数立即执行
excutor(resolve, reject);
}
status = PENDING;
value = undefined;
reason = undefined;
// 箭头函数让this一直指向这个对象。
resolve = value => {
if (this.status !== PENDING) return;
status = FULFILLED;
this.value = value;
}
reject = reason => {
if (this.status !== PENDING) return;
status = REJSCTED;
this.reason = reason;
}
then (successCallback, failCallback) {
if (this.status === FULFILLED) {
successCallback(this.value)
} else if (this.status === REJSCTED) {
failCallback(this.reason)
}
}
}
Promise 模拟源码————异步
当调用Promise 的时候调用执行器的时候,加一个setTimeout 因为上一个版本是同步执行的。 new MyPrimise()代码会立即执行。 而延时器并没有执行。 当执行栈所有东西执行完, MyPromisel里的状态还是pending的状态, 因为并没有传入改变状态的函数。 这个时候会执行到then方法里面。 但是我们只判断了成功和失败的处理方法。 这个时候我们需要加一个判断。 如果执行到then里面状态值是pending的时候。 我们用一个类的属性,将这个成功和失败的回调存起来。 这个时候会执行行延时器里面的东西。 这个时候调用成功的回调或者是失败的回调。 可以在失败或者成功的会回调里判断是否then里面存的函数。 如果有的话就执行。
const PENGING = 'pending';
const FULFILLED = 'fulilled';
const REJECTED = 'rejected';
class myPromise {
constructor (excutor) {
excutor(this.resolve, this.reject)
}
status = PENGING;
value = undefined;
reason = undefined;
successCallback = undefined;
failCallback = undefined;
resolve = value => {
//如果状态PENDING则继续执行。 否则阻止3执行
if (this.status !== PENGING) return
// 将状态更改为成功
this.status = FULFILLED;
// 保存成功之后的值。
this.value = value;
// 判断是否存在成功回调函数。
this.successCallback && this.successCallback(this.value)
}
reject = reason => {
//如果状态PENDING则继续执行。 否则阻止执行
if (this.status !== PENGING) return
// 将状态改为失败
this.status = REJECTED;
// 保存失败之后的原因。
this.reason = reason;
// 判断是否有失败回调函数。
this.failCallback && this.failCallback(this.reason);
}
then (successCallback, failCallback) {
if (this.status === FULFILLED) {
successCallback(this.value)
} else if (this.status === REJECTED) {
failCallback(this.reason)
} else {
this.successCallback = successCallback;
this.failCallback = failCallback;
}
}
}
module.exports = myPromise
多个then调用
思路将 successCallback = undefined; -> successCallback = []; failCallback = undefined; -> failCallback = []; 改成数组然后循环调用。
const PENGING = 'pending';
const FULFILLED = 'fulilled';
const REJECTED = 'rejected';
class myPromise {
constructor (excutor) {
excutor(this.resolve, this.reject)
}
status = PENGING;
value = undefined;
reason = undefined;
successCallback = [];
failCallback = [];
resolve = value => {
//如果状态PENDING则继续执行。 否则阻止3执行
if (this.status !== PENGING) return
// 将状态更改为成功
this.status = FULFILLED;
// 保存成功之后的值。
this.value = value;
// 判断是否存在成功回调函数。
while (this.successCallback.length) this.successCallback.shift()(this.value)
}
reject = reason => {
//如果状态PENDING则继续执行。 否则阻止执行
if (this.status !== PENGING) return
// 将状态改为失败
this.status = REJECTED;
// 保存失败之后的原因。
this.reason = reason;
// 判断是否有失败回调函数。
while (this.failCallback.length) this.failCallback.shift()(this.reason)
}
then (successCallback, failCallback) {
if (this.status === FULFILLED) {
successCallback(this.value)
} else if (this.status === REJECTED) {
failCallback(this.reason)
} else {
this.successCallback.push(successCallback);
this.failCallback.push(failCallback);
}
}
}
module.exports = myPromise
Promise 链式调用
分析: then方法链式调用。上一个then()方法返回值是 下一个then方法的接收值。也就是说返回是一个Promise 所以需要new Promise()
then (successCallback, failCallback) {
// new Promise 将上一次测返回值传到下一个接收。
let Promise2 = new myPromise((resolve, reject) => {
if (this.status === FULFILLED) {
resolve(successCallback(this.value))
} else if (this.status === REJECTED) {
failCallback(this.reason)
} else {
this.successCallback.push(successCallback);
this.failCallback.push(failCallback);
}
})
return Promise2;
}
判断then方法的返回值是什么 普通值还是Promise;
判断then方法的返回值是普通值还是Promise,如果是普通值就直接 返回。如果是promise就执行掉然后把结果返回。
then (successCallback, failCallback) {
let Promise2 = new myPromise((resolve, reject) => {
if (this.status === FULFILLED) {
const x = successCallback(this.value)
resolvePromise(x, resolve, reject)
} else if (this.status === REJECTED) {
failCallback(this.reason)
} else {
this.successCallback.push(successCallback);
this.failCallback.push(failCallback);
}
})
return Promise2;
}
function resolvePromise (x, resolve, reject) {
if (x instanceof myPromise) {
x.then(resolve, reject);
} else {
resolve(x);
}
}
判断自己返回自己的情况
then (successCallback, failCallback) {
let Promise2 = new myPromise((resolve, reject) => {
if (this.status === FULFILLED) {
setTimeout(() => {
const x = successCallback(this.value)
resolvePromise(Promise2, x, resolve, reject)
}, 0)
} else if (this.status === REJECTED) {
failCallback(this.reason)
} else {
this.successCallback.push(successCallback);
this.failCallback.push(failCallback);
}
})
return Promise2;
}
function resolvePromise (Promise2, x, resolve, reject) {
console.log(Promise2 === x, 8889999999)
if (Promise2 === x) return reject('不能循环调用自己')
if (x instanceof myPromise) {
x.then(resolve, reject);
} else {
resolve(x);
}
}
Promise 错误处理
- 将执行器try{}catch(){}捕获错误。
- then 方法成功的时候和失败的时候 还有异步处理的时候都需要
- 将错误捕获。 代码解析。
// Promise 的三个状态。
const PENGING = 'pending'; // 等待
const FULFILLED = 'fulilled'; // 成功
const REJECTED = 'rejected'; // 失败
// 创建Promise类。
class myPromise {
// 构造器传过来一个执行函数。
constructor (excutor) {
// 捕获执行器的错误。
try{
// 执行器执行 分别传出两个参数》函数 resolve reject
excutor(this.resolve, this.reject)
}
catch (err) {
// 报错执行错误函数。
this.reject(err.message)
}
}
// 记录Promise的状态
status = PENGING;
// 设置成功 默认值
value = undefined;
设置失败默认值
reason = undefined;
// 记录成功和失败函数数组。
successCallback = [];
failCallback = [];
// 成功执行函数
resolve = value => {
//如果状态PENDING则继续执行。 否则阻止执行
if (this.status !== PENGING) return
// 将状态更改为成功
this.status = FULFILLED;
// 保存成功之后的值。
this.value = value;
// 判断是否存在成功回调函数。
while (this.successCallback.length) this.successCallback.shift()()
}
// 失败执行函数。
reject = reason => {
//如果状态PENDING则继续执行。 否则阻止执行
if (this.status !== PENGING) return
// 将状态改为失败
this.status = REJECTED;
// 保存失败之后的原因。
this.reason = reason;
// 判断是否有失败回调函数。
while (this.failCallback.length) this.failCallback.shift()()
}
// 当 执行器执行完成之后执行then方法获取结果。
// 两个参数都是回调函数: successCallback failCallback
then (successCallback, failCallback) {
// then方法执行完都会返回一个新的Promise
let Promise2 = new myPromise((resolve, reject) => {
// 当上一个Promise执行完成的状态判断。成功 执行
if (this.status === FULFILLED) {
// 与同步之后执行为了获取到Promise2对象构造完成。
// const x = successCallback(this.value)必须正在延迟器里调用的return 的对象才能接受到。
setTimeout(() => {
try {
// 调用者返回的值
const x = successCallback(this.value)
// 解析Promise传过来的值。
resolvePromise(Promise2, x, resolve, reject)
}
catch(err) {
// catch 掉错误在下一个then方法 显示、
reject(err.message)
}
}, 0)
// 当上一个Promise执行完成的状态判断。失败 执行
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
const x = failCallback(this.reason)
resolvePromise(Promise2, x, resolve, reject)
}
catch(err) {
reject(err.message)
}
}, 0)
} else {
this.successCallback.push(() => {
setTimeout(() => {
try {
const x = successCallback(this.value)
resolvePromise(Promise2, x, resolve, reject)
}
catch(err) {
reject(err.message)
}
}, 0)
});
this.failCallback.push(() => {
setTimeout(() => {
try {
const x = failCallback(this.reason)
resolvePromise(Promise2, x, resolve, reject)
}
catch(err) {
reject(err.message)
}
}, 0)
});
}
})
return Promise2;
}
}
/**
* 解析Promise
* Promise2 then方法返回的新的Promise
* x 调用者返回的参数: 可以是普通参数也可以是别的
* 如果参数是它 new Promise 本身的我们需要特殊处理下。
*/
function resolvePromise (Promise2, x, resolve, reject) {
// 如果返回本身的话报错提示下
if (Promise2 === x) return reject('不能循环调用自己')
// 如果是调用者new Primise 我们 需要把这个Promise执行掉。然后返回结果。
if (x instanceof myPromise) {
x.then(resolve, reject);
} else {
// 如果是正常的值不是Promise的话我们直接返回。
resolve(x);
}
}
module.exports = myPromise
将then 方法参数变成可选参数
// 如果没有传参数的话就把上一个Promise执行的结果返回给下下一个参数。
successCallback = successCallback ? successCallback : value => value;
failCallback = failCallback ? failCallback : value => value;