赞
踩
用法不再多说,只是展示比较跟我下面写的使用方法
var p = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve(4)
}, 0)
})
p.then((res)=>{
//4 res
console.log(res, 'res')
})
const p = new Promise((resolve, reject) => { setTimeout(() => { // resolve(4); // eslint-disable-next-line prefer-promise-reject-errors reject(4); }, 0); }); p.then( (res) => { console.log(res, 'res'); }, (err) => { // 4 err console.log(err, 'err'); }, );
const p = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve(4);
// eslint-disable-next-line prefer-promise-reject-errors
reject(4);
}, 0);
});
p.then((res) => {
console.log(res, 'res');
}).catch((e) => {
// 4
console.log(e);
});
我们这里可以看到如果写入then
第二个参数后,可以处理reject
的值,也可以通过catch
来处理reject
的值
class MyPromise {
public constructor(fn: (resolve: (value: unknown) => void) => void) {
// 成功
const resolve = (value: unknown) => {
console.log(value);
};
fn(resolve);
}
}
const a = new MyPromise((resolve) => {
resolve('123');
/** 123 */
});
这样我们创建一个类,具有回调对象里面函数的方法。
const PENDING = 'pending'; // 等待中 const FULFILLED = 'fulfilled'; // 执行 const REJECTED = 'rejected'; // 拒绝 class MyPromise { /** 执行状态 */ state = PENDING; /** 执行返回 */ value: any = null; /** 失败返回 */ reason: any = null; public constructor( fn: (resolve: (value: unknown) => void, reject: (reason: unknown) => void) => void, ) { const resolve = (value: unknown) => { // state改变,resolve调用就会失败 if (this.state === 'pending') { // resolve调用后,state转化为成功态 this.state = 'fulfilled'; // 储存成功的值 this.value = value; console.log(value); } }; const reject = (reason: unknown) => { // state改变,reject调用就会失败 if (this.state === 'pending') { // reject调用后,state转化为失败态 this.state = 'rejected'; // 储存失败的原因 this.reason = reason; } }; // 如果executor执行报错,直接执行reject try { fn(resolve, reject); } catch (err) { reject(err); } } } const a = new MyPromise((resolve) => { resolve('123'); /** 123 */ });
现在跟Promise 使用方法还差一个then方法进行回调resolve
方法
3.
then
的方法,里面有两个参数:onFulfilled
,onRejected
,成功有成功的值,失败有失败的原因state
为fulfilled
,则执行onFulfilled
,传入this.value
。当状态state
为rejected
,则执行onRejected
,传入this.value
onFulfilled
,onRejected
如果他们是函数,则必须分别在fulfilled
,rejected
后被调用,value
或reason
依次作为他们的第一个参数。Promise
,可以看得到resolve
传进去就是4
,这个值会传进then
里面的res
就是上面提到onFulfilled
var p = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve(4)
}, 0)
})
p.then((res)=>{
//4 res
console.log(res, 'res')
})
const PENDING = 'pending'; // 等待中 const FULFILLED = 'fulfilled'; // 执行 const REJECTED = 'rejected'; // 拒绝 class MyPromise { /** 执行状态 */ state = PENDING; /** 执行返回 */ value: any = null; /** 失败返回 */ reason: any = null; public constructor( fn: (resolve: (value: unknown) => void, reject: (reason: unknown) => void) => void, ) { const resolve = (value: unknown) => { // state改变,resolve调用就会失败 if (this.state === 'pending') { // resolve调用后,state转化为成功态 this.state = 'fulfilled'; // 储存成功的值 this.value = value; } }; const reject = (reason: unknown) => { // state改变,reject调用就会失败 if (this.state === 'pending') { // reject调用后,state转化为失败态 this.state = 'rejected'; // 储存失败的原因 this.reason = reason; } }; // 如果executor执行报错,直接执行reject try { fn(resolve, reject); } catch (err) { reject(err); } } // then 方法 有两个参数onFulfilled onRejected then(onFulfilled?: Function, onRejected?: Function) { // 状态为fulfilled,执行onFulfilled,传入成功的值 if (onFulfilled && this.state === 'fulfilled') { onFulfilled(this.value); } // 状态为rejected,执行onRejected,传入失败的原因 if (onRejected && this.state === 'rejected') { onRejected(this.reason); } } } const a = new MyPromise((resolve) => { resolve('123'); }); a.then((res: string) => { console.log(res); // 123 });
resolve
在setTomeou
t内执行,then
时state
还是pending
等待状态 我们就需要在then调用的时候,将成功和失败存到各自的数组,一旦reject
或者resolve
,就调用它们,优化一下代码enum Status { PENDING = 'pending', // 等待中 FULFILLED = 'fulfilled', // 执行 REJECTED = 'rejected', // 拒绝 } class MyPromise { /** 执行状态 */ state: Status = Status.PENDING; /** 执行返回 */ value: any = null; /** 失败返回 */ reason: any = null; /** 成功存放的数组 */ onResolvedCallbacks: Function[] = []; /** 失败存放法数组 */ onRejectedCallbacks: Function[] = []; public constructor( fn: (resolve: (value: unknown) => void, reject: (reason: unknown) => void) => void, ) { const resolve = (value: unknown) => { // state改变,resolve调用就会失败 if (this.state === Status.PENDING) { // resolve调用后,state转化为成功态 this.state = Status.FULFILLED; // 储存成功的值 this.value = value; // 一旦resolve执行,调用成功数组的函数 this.onResolvedCallbacks.forEach((fn) => fn()); } }; const reject = (reason: unknown) => { // state改变,reject调用就会失败 if (this.state === Status.PENDING) { // reject调用后,state转化为失败态 this.state = Status.REJECTED; // 储存失败的原因 this.reason = reason; // 一旦reject执行,调用失败数组的函数 this.onRejectedCallbacks.forEach((fn) => fn()); } }; // 如果executor执行报错,直接执行reject try { fn(resolve, reject); } catch (err) { reject(err); } } // then 方法 有两个参数onFulfilled onRejected then(onFulfilled?: Function, onRejected?: Function) { if (this.state === Status.FULFILLED && onFulfilled) { onFulfilled(this.value); } if (this.state === Status.REJECTED && onRejected) { onRejected(this.reason); } // 当状态state为pending时 if (this.state === Status.PENDING) { if (onFulfilled && typeof onFulfilled === 'function') { // onFulfilled传入到成功数组 this.onResolvedCallbacks.push(() => { onFulfilled(this.value); }); } if (onRejected && typeof onRejected === 'function') { // onRejected传入到失败数组 this.onRejectedCallbacks.push(() => { onRejected(this.value); }); } } } } const a = new MyPromise((resolve) => { setTimeout(() => { console.log('444'); resolve('123'); }, 500); console.log('333'); }); a.then((res: string) => { console.log(res); }); // 333 444 123 最终结果
then
使用, new Promise().then().then() ,这就是链式调用,用来解决回调地狱。const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(4);
// eslint-disable-next-line prefer-promise-reject-errors
// reject(4);
}, 0);
});
p.then((res) => {
// 4 res
console.log(res, 'res');
return res + 1;
}).then((res) => {
// 5 res2
console.log(res, 'res2');
});
1、为了达成链式,我们默认在第一个then里返回一个promise。秘籍规定了一种方法,就是在then里面返回一个新的promise,称为promise2: promise2 = new Promise((resolve, reject)=>{})
•将这个promise2返回的值传递到下一个then中
•如果返回一个普通的值,则将普通的值传递给下一个then中
2、当我们在第一个then中 return 了一个参数(参数未知,需判断)。这个return出来的新的promise就是onFulfilled()或onRejected()的值
秘籍则规定onFulfilled()或onRejected()的值,即第一个then返回的值,叫做x,判断x的函数叫做resolvePromise
回归我们代码
enum Status { PENDING = 'pending', // 等待中 FULFILLED = 'fulfilled', // 执行 REJECTED = 'rejected', // 拒绝 } class MyPromise { /** 执行状态 */ state: Status = Status.PENDING; /** 执行返回 */ value: any = null; /** 失败返回 */ reason: any = null; /** 成功存放的数组 */ onResolvedCallbacks: Function[] = []; /** 失败存放法数组 */ onRejectedCallbacks: Function[] = []; /** 构造方法 是一个方法,里面有2个传参,第一个是 resolve 是方法传参是 成功回调传参, 第二个是reject方法 里面的参数是失败回调 */ public constructor( fn: (resolve: (value: unknown) => void, reject: (reason: unknown) => void) => void, ) { const resolve = (value: unknown) => { // state改变,resolve调用就会失败 if (this.state === Status.PENDING) { // resolve调用后,state转化为成功态 this.state = Status.FULFILLED; // 储存成功的值 this.value = value; // 一旦resolve执行,调用成功数组的函数 this.onResolvedCallbacks.forEach((fn) => fn()); } }; const reject = (reason: unknown) => { // state改变,reject调用就会失败 if (this.state === Status.PENDING) { // reject调用后,state转化为失败态 this.state = Status.REJECTED; // 储存失败的原因 this.reason = reason; // 一旦reject执行,调用失败数组的函数 this.onRejectedCallbacks.forEach((fn) => fn()); } }; // 如果executor执行报错,直接执行reject try { fn(resolve, reject); } catch (err) { reject(err); } } // then 方法 有两个参数onFulfilled 是指 then(res)的res res 就是 resolve()传进去的值 onRejected then(onFulfilled?: Function, onRejected?: Function) { // 声明返回的promise2 const promise2 = new MyPromise((resolve, reject) => { if (this.state === Status.FULFILLED && onFulfilled) { const x = onFulfilled(this.value); this.resolvePromise(promise2, x, resolve, reject); } if (this.state === Status.REJECTED && onRejected) { const x = onRejected(this.reason); this.resolvePromise(promise2, x, resolve, reject); } // 当状态state为pending时 if (this.state === Status.PENDING) { if (onFulfilled && typeof onFulfilled === 'function') { // onFulfilled传入到成功数组 this.onResolvedCallbacks.push(() => { const x = onFulfilled(this.value); this.resolvePromise(promise2, x, resolve, reject); }); } if (onRejected && typeof onRejected === 'function') { // onRejected传入到失败数组 this.onRejectedCallbacks.push(() => { const x = onRejected(this.value); this.resolvePromise(promise2, x, resolve, reject); }); } } }); return promise2; } resolvePromise( promise2: MyPromise, x: any, resolve: (value: unknown) => void, reject: (value: unknown) => void, ) { if (promise2 === x) { return reject(new TypeError('Chaining cycle detected for promise #<promise>')); } // 判断如果x是否是一个对象,判断函数是否是对象的方法有:typeof instanceof constructor toString if ((typeof x === 'object' && x != null) || typeof x === 'function') { try { const then = x.then; // 取then可以报错,报错就走reject() if (typeof then === 'function') { // 用then.call()为了避免在使用一次x.then报错 then.call( x, (y: any) => { console.log('y', y); resolve(y); // 采用promise的成功结果,并且向下传递 }, (r: any) => { reject(r); // 采用promise的失败结果,并且向下传递 }, ); } else { resolve(x); // x不是一个函数,是一个对象 } } catch (err) { reject(err); } } else { // x是一个普通值 resolve(x); } } }
new MyPromise((resolve) => { setTimeout(() => { console.log('开始'); resolve('a'); }, 500); }) .then((res: string) => { console.log(res); console.log('结束'); return 'b'; }) .then((res: string) => { console.log(res); }); new Promise((resolve) => { resolve('a'); }) .then((res: any) => { console.log(res); return 'b'; }) .then((res: string) => { console.log(res); });
结果都是一样的可以使用
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。