promise
time 2m41s
class MyPromise {constructor() {}}/*换成mypromise*/// const p1 = new Promise((resolve, reject) => {const p1 = new MyPromise((resolve, reject) => {resolve(1);})p1.then((res) => {console.log(res);}, err => {console.log(err);})/*1*/
第一步
time 5m54s
class MyPromise {constructor(executor) {this.state = 'pending';this.value = undefined;this.reason = undefined;let resolve = (value) => {this.state = 'fullFilled';this.value = value}let reject = (reason) => {this.state = 'rejected';this.reason = reason;}executor(resolve, reject);}then(onFullFilled, onRejected) {if (this.state === 'fullFilled') {onFullFilled(this.value);}if (this.state === 'rejected') {onRejected(this.reason);}}}/*换成mypromise*/// const p1 = new Promise((resolve, reject) => {const p1 = new MyPromise((resolve, reject) => {resolve(1);})p1.then((res) => {console.log(res);}, err => {console.log(err);})/*1*/
分析
1可以new MyPromise(参数xx),说明需要在constructor构造函数中写,定义
先把需要的方法、参数写了。参数executor,resolve, reject。参数是什么?是方法,补上resolve,reject,不然报错,补上then方法,使得函数运行不报错
2方法有了,需要干什么有了,之后需要数据,开始声明变量,this.变量可以使得在构造函数声明的变量,在构造函数外也可以使用,在then方法中也可以使用
state变量用来记录状态信息,记录状态数据,value储存resolve传入的value的值,同理
3then方法分析p1.then,传入的是两个参数, then(onFullFilled, onRejected)先写上,两个回调函数onFullFilled(this.value),判断state走相应的回调函数,
p1.then((res) => {console.log(res);}, err => {console.log(err);})
这时传到两个函数,是作为参数,作为实参传入,并不会在p1.then的时候运行,是交给p1去调用,不是直接运行。
p1调用两个回调函数,决定它们何时运行,运不运行,err的可能都不会运行,传入的实参,不一定会运行
promise是一个控制方法运行的东西,的容器,实际运行的方法,实际的方法成千上万,有各种各样的方法,这些都是传入的回调函数决定的,promise只管控制它们。具体方法的实现不管。
处理异步
time 6m35s
class MyPromise {constructor(executor) {this.state = 'pending';this.value = undefined;this.reason = undefined;this.onFullFilledCallbacks = [];this.onRejectedCallbacks = [];let resolve = (value) => {this.state = 'fullFilled';this.value = value;// this.onFullFilledCallbacks.forEach(fn => fn(this.value));this.onFullFilledCallbacks.forEach(fn => fn());}let reject = (reason) => {this.state = 'rejected';this.reason = reason;// this.onRejectedCallbacks.forEach(fn => fn(this.value));this.onRejectedCallbacks.forEach(fn => fn());}executor(resolve, reject);}then(onFullFilled, onRejected) {if (this.state === 'fullFilled') {onFullFilled(this.value);}if (this.state === 'rejected') {onRejected(this.reason);}if (this.state === 'pending') {/* this.onFullFilledCallbacks.push(onFullFilled);this.onRejectedCallbacks.push(onRejected);*/this.onFullFilledCallbacks.push(() => {onFullFilled(this.value);});this.onRejectedCallbacks.push(()=>{onRejected(this.reason);});}}}/*换成mypromise*/// const p1 = new Promise((resolve, reject) => {const p1 = new MyPromise((resolve, reject) => {setTimeout(() => {resolve(1);}, 1000)})p1.then((res) => {console.log(res);}, err => {console.log(err);})p1.then((res) => {console.log(res);}, err => {console.log(err);})/*1 1*/
解析思路
因为异步操作setTimeout运行时,p1这是其实并没有运行完成
如同
let a = () => {setTimeout(() => {return 1;})}let n = a();console.log(n)/*undefined*/
打印undefined,因为let a声明,let n声明赋值,console是同步代码,先运行
setTimeout后运行,等它们运行完之后再运行。
let n声明赋值不会等待a()里面的setTimeout运行完了,返回值了之后再去运行,所以只能拿到undefined
let n = a();运行n=undefined,之后console运行,同步代码等待执行
怎么解决这个问题?
不运行,而是放入数组
if (this.state === 'pending') {/* this.onFullFilledCallbacks.push(onFullFilled);this.onRejectedCallbacks.push(onRejected);*/this.onFullFilledCallbacks.push(() => {onFullFilled(this.value);});this.onRejectedCallbacks.push(()=>{onRejected(this.reason);});}
异步情况,state明显是pedding,把回调函数与参数放入方法中,把回调函数运行放入方法中,方法不运行,回调函数也不会直接运行,用方法存储回调函数的运行,为了以后可以运行,之后运行这个函数,就可以直接运行回调函数了,不用传参,不管最后运不运行都要放进去,防止万一运行,万一之后用到
用数组放入函数,为了防止多个p1.then调用
onFullFilled(this.value)的value是实参,实参是在resolve(1);时传入的
这里面res是形参,不是传入的数据
p1.then((res) => {console.log(res);}, err => {console.log(err);})
再通过 this.onFullFilledCallbacks.forEach(fn => fn());遍历函数让其运行
let resolve = (value) => {this.state = 'fullFilled';this.value = value;// this.onFullFilledCallbacks.forEach(fn => fn(this.value));this.onFullFilledCallbacks.forEach(fn => fn());}
此时then是存入回调函数不运行,运行不由then控制
resolve(1);控制运行传入的回调函数,等setTimeout运行完,resolve运行
步骤
1pedding情况的建立
2两个储存回调数组的建立
3数组储存回调方法
4从数组中提取方法
处理链式操作
time 10m20s
class MyPromise {constructor(executor) {this.state = 'pending';this.value = undefined;this.reason = undefined;this.onFullFilledCallbacks = [];this.onRejectedCallbacks = [];let resolve = (value) => {this.state = 'fullFilled';this.value = value;// this.onFullFilledCallbacks.forEach(fn => fn(this.value));this.onFullFilledCallbacks.forEach(fn => fn());}let reject = (reason) => {this.state = 'rejected';this.reason = reason;// this.onRejectedCallbacks.forEach(fn => fn(this.value));this.onRejectedCallbacks.forEach(fn => fn());}executor(resolve, reject);}then(onFullFilled, onRejected) {let x;/*因为判断是同步执行的*/const p2 = new MyPromise((resolve, reject) => {if (this.state === 'fullFilled') {x = onFullFilled(this.value);// console.log('165:'+x)resolve(x);}if (this.state === 'rejected') {x = onRejected(this.reason);resolve(x);}if (this.state === 'pending') {/* this.onFullFilledCallbacks.push(onFullFilled);this.onRejectedCallbacks.push(onRejected);*/this.onFullFilledCallbacks.push(() => {x= onFullFilled(this.value);resolve(x);});this.onRejectedCallbacks.push(() => {x= onRejected(this.reason);resolve(x);});}})return p2;}}/*换成mypromise*/// const p1 = new Promise((resolve, reject) => {const p1 = new MyPromise((resolve, reject) => {// setTimeout(() => {// resolve(1);reject(1);// }, 1000)})const p2 = p1.then((res) => {// console.log(res);return res + 1;}, err => {// console.log(err)return err + 2;})p2.then(res => {console.log(res,'success');}, err => {console.log(err,'error');})/*3 success*/
解析
返回的也是promise,then返回的是promise,new promise返回的也是promise,
1then返回new promise的p2,即使是第一次调用then时,也是返回一个新的promise对象,所以每次then都新建new Promise新建p2
p2.then(res => {console.log(res, 'success');}, err => {console.log(err, 'error');}).then(res => {console.log(res, 'success');}, err => {console.log(err, 'error');})

第二次都是undefined
x = onFullFilled(this.value);的返回值是由
const p2 = p1.then((res) => {// console.log(res);return res + 1;}, err => {// console.log(err)return err + 2;})
return出去的,x赋值为res+1,是then执行时,传入的回调函数,不立刻执行,之后执行的,是回调函数return的
x = onFullFilled(this.value);onFullFilled是形参,在这里面指代实参
x=(res) => {// console.log(res);return res + 1;}
如果console,没有传值就是undefined
onFullFilled(this.value)中this.value相当于函数运行,传实参,res =this.value,传参并运行
为什么需要resolve(x)?
因为onFullFilled(this.value)需要新的this.value,每次链式操作拿到新的this.value,需要让它重新赋值,让this.value改变成回调函数return的值,在代码
let resolve = (value) => {this.state = 'fullFilled';this.value = value;this.onFullFilledCallbacks.forEach(fn => fn());}
中,有改变value的值,并且如果一开始是reject,之后运行也需要改变之前的state的值,由失败变成功
处理new MyPromise
time 16m35s
class MyPromise {constructor(executor) {this.state = 'pending';this.value = undefined;this.reason = undefined;this.onFullFilledCallbacks = [];this.onRejectedCallbacks = [];let resolve = (value) => {this.state = 'fullFilled';this.value = value;// this.onFullFilledCallbacks.forEach(fn => fn(this.value));this.onFullFilledCallbacks.forEach(fn => fn());}let reject = (reason) => {this.state = 'rejected';this.reason = reason;// this.onRejectedCallbacks.forEach(fn => fn(this.value));this.onRejectedCallbacks.forEach(fn => fn());}// executor(resolve, reject);try {executor(resolve, reject);} catch (err) {reject(err)}}then(onFullFilled, onRejected) {/*因为判断是同步执行的*/const p2 = new MyPromise((resolve, reject) => {let x;if (this.state === 'fullFilled') {/*让resolvePromise(p2, x, resolve, reject);之后再运行,如果p2声明赋值时*/setTimeout(() => {try {x = onFullFilled(this.value);// console.log(172, x);resolvePromise(p2, x, resolve, reject);} catch (err) {reject(err)}}, 0)/* x = onFullFilled(this.value);// console.log('165:'+x)// resolve(x);resolvePromise(p2, x, resolve, reject)*/}if (this.state === 'rejected') {setTimeout(() => {try {x = onRejected(this.reason);resolvePromise(p2, x, resolve, reject);} catch (err) {reject(err)}}, 0)}if (this.state === 'pending') {/* this.onFullFilledCallbacks.push(onFullFilled);this.onRejectedCallbacks.push(onRejected);*/this.onFullFilledCallbacks.push(() => {setTimeout(() => {try {x = onFullFilled(this.value);resolvePromise(p2, x, resolve, reject);} catch (err) {reject(err)}}, 0)});this.onRejectedCallbacks.push(() => {setTimeout(() => {try {x = onRejected(this.reason);resolvePromise(p2, x, resolve, reject);} catch (err) {reject(err)}}, 0)/* x = onRejected(this.reason);// resolve(x);resolvePromise(p2, x, resolve, reject);*/});}})return p2;}}function resolvePromise(p2, x, resolve, reject) {// console.log(192, p2, x, resolve, reject);// console.log(209,a);if (p2 === x) {reject(new TypeError('typeErr'));}/*x可以是个方法,再return出去一个值*/if ((typeof x === 'object' && x != null) || x === 'function') {try {/*thenable对象,这是处理return new Promise的情况*/let then = x.then;if (typeof then === 'function') {/* then.call(x是让then需要上下文,让then的上下文,变成x,变成* 返回的promise,相当于返回的promise.then*/then.call(x, y => {/*x.then值是一样的*/// x.then(y => {/*这时then独立调用指向window*/// then(y=>{console.log(250, y);resolve(y);}, r => {console.log(252, r);reject(r);})} else {resolve(x);}} catch (err) {reject(err);}} else {resolve(x);}}/*换成mypromise*/// const p1 = new Promise((resolve, reject) => {const p1 = new MyPromise((resolve, reject) => {// setTimeout(() => {resolve(1);// reject(1);// }, 1000)})const p2 = p1.then((res) => {// console.log(res);// return res + 1;/*返回值是一个Promise,想要拿到里面的reject,怎么拿到,需要通过得到它xx,* xx.then的方式得到10*/return new MyPromise((resolve, reject) => {reject(10);})}, err => {// console.log(err)return err + 2;})p2.then(res => {console.log(266, res, 'success');}, err => {console.log(268, err, 'error');})
锁
time 34m06s
function resolvePromise(p2, x, resolve, reject) {// console.log(192, p2, x, resolve, reject);// console.log(209,a);let called;if (p2 === x) {reject(new TypeError('typeErr'));}/*x可以是个方法,再return出去一个值*/if ((typeof x === 'object' && x != null) || x === 'function') {try {/*thenable对象,这是处理return new Promise的情况*/let then = x.then;if (typeof then === 'function') {/* then.call(x是让then需要上下文,让then的上下文,变成x,变成* 返回的promise,相当于返回的promise.then*/then.call(x, y => {/*x.then值是一样的*/// x.then(y => {/*这时then独立调用指向window*/// then(y=>{if (called) return;called = true;console.log(250, y);resolve(y);}, r => {if (called) return;called = true;console.log(252, r);reject(r);})} else {if (called) return;called = true;resolve(x);}} catch (err) {if (called) return;called = true;reject(err);}} else {/*这里不需要锁了*/resolve(x);}}
func
const isFunction = (value) => typeof value === 'function';then(onFullFilled, onRejected) {onFullFilled = isFunction(onFullFilled) ? onFullFilled : data => data;onRejected = isFunction(onRejected) ? onRejected : err => {throw err;};
判断是否符合规范
time 37m38s
npm install promises-aplus-tests
promises-aplus-test app.js
