Promise的使用和简易封装(后续更新Promise.all等)
-
使用场景:Promise在前端中主要处理网络请求
-
Promise是一个构造函数。
-
Promise有三种状态
待定(pending): 初始状态,既没有被兑现,也没有被拒绝。
已兑现(fulfilled): 意味着操作成功完成。
已拒绝(rejected): 意味着操作失败。 -
使用方式
const promise = new Promise((resolve, reject) => { // 发送网络请求等异步操作 // 本文通过定时器模拟异步操作 setTimeout(() => { resolve({succeed: true, data: {}}); }, 3000) }).then(res => { // then方法传入的函数即为上面的resolve函数,接收的数据即为res console.log(res); }).catch(err => { // catch方法传入的函数即为上面的reject函数,接收的数据即为err console.log(err); });
-
代码解读
Promise接收一个参数,这个参数是包含两个参数的函数(以下称为fn);
fn函数的这两个参数分别是resolve函数和reject函数,而这两个函数一开始并没有实际的值,而是在Promise对象被构建时在then函数和catch函数中传入的。意为当Promise中传入的fn执行完操作后,Promise对象判断此时的状态是从pending转换为fulfilled还是从pending装换为rejected,然后决定调用执行then函数中传入的函数还是catch函数中传入的函数,理解了上边这段话,Promise其实也就没那么神秘了。 -
Promise的简易封装
class MyPromise { state = 'pending'; succeed = null; fail = null; fn = null; constructor(fn) { // 保存fn作为then的返回值函数的参数传入 this.fn = fn; // 调用失败时调用 try { fn(this.resolve.bind(this), this.reject.bind(this)); } catch(e) { this.fail && this.fail(e); } } resolve(result) { setTimeout(() => { this.state = 'fulfilled'; this.succeed && this.succeed(result); }); } reject(reason) { setTimeout(() => { this.state = 'rejected'; this.fail && this.fail(reason); }); } // fail非必填 then(succeed, fail = null) { this.succeed = succeed; fail ? this.fail = fail : ''; return new MyPromise(this.fn); } catch(fail) { this.fail = fail; } } // then/catch分开调用 let myPromise1 = new MyPromise((resolve, reject) => { setTimeout(() => { resolve('myPromise1 success'); }, 1000); }).then(res => { console.log(res); }).catch(err => { console.log(err); }); // then直接调用 let myPromise2 = new MyPromise((resolve, reject) => { setTimeout(() => { resolve('myPromise2 success'); }, 1000); }).then(res => { console.log(res); }, err => { console.log(err); });