Promise 实现
-
- Promise 就是一个类,执行这个类的时候,需要传递一个回调函数进去 — 执行器(立即执行)
- 执行器会接受两个参数,实际就是两个函数,调用时实际上是修改Promise的状态
-
- 三种状态:成功 fulfilled、失败 rejected、等待 pending
- pending --> fulfilled
- pending --> rejected
- 一旦状态确定就不可更改
-
- resolve和rejected函数是用来更改状态的
- resolve: fulfilled
- reject: rejected
-
- then方法内部做的事情其实就是判断状态
- 如果状态是成功就调用成功的回调函数,如果状态是失败就调用失败的回调函数
- then方法是被定义在原型对象当中的
-
- then成功回调有一个参数 表示成功之后的值 then失败回调有一个参数 表示失败的原因
-
- Promise支持异步调用
- then方法内部的判断状态加上一个等待状态
- 等待状态时就将成功回调或者失败回调存储一下
-
- 同一个promise对象下的then方法是可以多次调用的,当then方法被多次调用时,每一个then方法中传递的回调函数都是要被执行的
-
- then方法是可以被链式调用的,后面then方法的回调函数拿到值的是上一个then方法的回调函数的返回值
- 实现then方法的链式调用
- then方法是promise方法下边的,想要实现链式调用,那就要返回一个promise对象
- 把上一个then方法的回调函数中的返回值传递给下一个then方法的回调函数
- 在链式调用then方法时,在then方法的回调函数当中,我们可以去返回一个普通值,也可以去返回一个Promise对象,如果是普通值,直接通过resolve传递就可以了,如果是Promise对象的话,我们要先去查看返回的promise对象状态,成功状态就要调用resolve方法把这个状态传递给下一个对象,如果是失败就要调用reject方法,把这个状态传递给下一个对象
-
- 错误处理,为了程序的健壮性,我们还是有必要去捕获错误,处理错误
- 当执行器当中的代码在执行的过程当中发生错误的时候,这个时候我们就让promise的状态变成失败
- 也就是在then的第二个参数的地方捕获到错误
核心逻辑实现
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
constructor (executor) {
executor(this.resolve, this.reject)
}
status = PENDING;
value = undefined
reason = undefined
resolve = value => {
if(this.status !== PENDING) return
this.status = FULFILLED
this.value = value;
}
reject = reason => {
if(this.status !== PENDING) return
this.status = REJECTED
this.reason = reason;
}
then (successCallback, failCallback) {
if(this.status === FULFILLED){
successCallback(this.value)
} else if(this.status === REJECTED) {
failCallback(this.reason)
}
}
}
module.exports = MyPromise;
const MyPromise = require('./02-Promise核心逻辑实现');
let promise = new MyPromise((resolve, reject) => {
resolve('成功')
reject('失败')
})
promise.then(value => {
console.log(value)
}, reason => {
console.log(reason)
})
加入异步逻辑实现
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
constructor (executor) {
executor(this.resolve, this.reject)
}
status = PENDING;
value = undefined;
reason = undefined;
successCallback = undefined;
failCallback = undefined;
resolve = value => {
if(this.status !== PENDING) return;
this.status = FULFILLED;
this.value = value;
this.successCallback ? this.successCallback(this.value) : null
}
reject = reason => {
if(this.status !== PENDING) 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;
const MyPromise = require('./02.1-Promise异步逻辑实现');
let promise = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve('成功')
}, 2000)
})
promise.then(value => {
console.log(value)
}, reason => {
console.log(reason)
})
then方法的多次调用
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
constructor (executor) {
executor(this.resolve, this.reject)
}
status = PENDING;
value = undefined;
reason = undefined;
successCallback = [];
failCallback = [];
resolve = value => {
if(this.status !== PENDING) return;
this.status = FULFILLED;
this.value = value;
while (this.successCallback.length) this.successCallback.shift()(this.value)
}
reject = reason => {
if(this.status !== PENDING) 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;
const MyPromise = require('./03.1-Promise-then方法多次调用');
let promise = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve('成功了233333')
}, 2000)
})
promise.then(value => {
console.log(1)
console.log(value)
}, (reason) => {
console.log(reason)
})
promise.then(value => {
console.log(2)
console.log(value)
}, (reason) => {
console.log(reason)
})
promise.then(value => {
console.log(3)
console.log(value)
}, (reason) => {
console.log(reason)
})
then方法的链式调用上
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
constructor (executor) {
executor(this.resolve, this.reject)
}
status = PENDING;
value = undefined;
reason = undefined;
successCallback = [];
failCallback = [];
resolve = value => {
if(this.status !== PENDING) return;
this.status = FULFILLED;
this.value = value;
while (this.successCallback.length) this.successCallback.shift()(this.value)
}
reject = reason => {
if(this.status !== PENDING) 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;
const MyPromise = require('./04.1-Promise-then方法链式调用');
let promise = new MyPromise((resolve, reject) => {
resolve('成功')
})
promise.then(value => {
console.log(value)
return 100
}).then(value => {
console.log(value)
})
then方法的链式调用下
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
constructor(executor) {
executor(this.resolve, this.reject)
}
status = PENDING;
value = undefined;
reason = undefined;
successCallback = [];
failCallback = [];
resolve = value => {
if (this.status !== PENDING) return;
this.status = FULFILLED;
this.value = value;
while (this.successCallback.length) this.successCallback.shift()(this.value)
}
reject = reason => {
if (this.status !== PENDING) return;
this.status = REJECTED;
this.reason = reason;
while (this.failCallback.length) this.failCallback.shift()(this.reason)
}
then(successCallback, failCallback) {
let promise2 = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
let 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)
}
}
module.exports = MyPromise;
const MyPromise = require('./04.3-Promise-then方法链式调用');
let promise = new MyPromise((resolve, reject) => {
resolve('成功')
})
function other () {
return new MyPromise((resolve, reject) => {
resolve('othen');
})
}
promise.then(value => {
console.log(value)
return other()
}).then(value => {
console.log(value)
})
then方法链式调用识别Promise对象自动返回
const MyPromise = require('./05.1-识别Promise对象自动返回');
let promise = new MyPromise((resolve, reject) => {
resolve('成功')
})
let p1 = promise.then(value => {
console.log(value)
return p1;
})
p1.then(value => {
console.log(value)
}, reason => {
console.log(reason.message)
})
var promise = new Promise(function (resolve, reject) {
resolve(100)
})
var p1 = promise.then(function (value) {
console.log(value)
return p1
})
p1.then(function () {}, function (reason) {
console.log(reason.message)
})
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
constructor(executor) {
executor(this.resolve, this.reject)
}
status = PENDING;
value = undefined;
reason = undefined;
successCallback = [];
failCallback = [];
resolve = value => {
if (this.status !== PENDING) return;
this.status = FULFILLED;
this.value = value;
while (this.successCallback.length) this.successCallback.shift()(this.value)
}
reject = reason => {
if (this.status !== PENDING) return;
this.status = REJECTED;
this.reason = reason;
while (this.failCallback.length) this.failCallback.shift()(this.reason)
}
then(successCallback, failCallback) {
let promise2 = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
setTimeout(() => {
let 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) {
if(promise2 === x){
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof MyPromise) {
x.then(resolve, reject)
} else {
resolve(x)
}
}
module.exports = MyPromise;
捕获错误与then链式调用其他状态
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
constructor(executor) {
try {
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e);
}
}
status = PENDING;
value = undefined;
reason = undefined;
successCallback = [];
failCallback = [];
resolve = value => {
if (this.status !== PENDING) return;
this.status = FULFILLED;
this.value = value;
while (this.successCallback.length) this.successCallback.shift()()
}
reject = reason => {
if (this.status !== PENDING) return;
this.status = REJECTED;
this.reason = reason;
while (this.failCallback.length) this.failCallback.shift()()
}
then(successCallback, failCallback) {
let promise2 = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
setTimeout(() => {
try {
let x = successCallback(this.value)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = failCallback(this.reason)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else {
this.successCallback.push(() => {
setTimeout(() => {
try {
let x = successCallback(this.value)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
});
this.failCallback.push(() => {
setTimeout(() => {
try {
let x = failCallback(this.reason)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
});
}
});
return promise2;
}
}
function resolvePromise(promise2, x, resolve, reject) {
if(promise2 === x){
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof MyPromise) {
x.then(resolve, reject)
} else {
resolve(x)
}
}
module.exports = MyPromise;
const MyPromise = require('./07.1-捕获错误与then链式调用其他状态');
let promise = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve('2000')
}, 2000)
})
promise.then(value => {
console.log(value)
return 123
}, reason => {
return 10000
}).then(value => {
console.log(value)
})
then方法参数变为可选
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
constructor(executor) {
try {
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e);
}
}
status = PENDING;
value = undefined;
reason = undefined;
successCallback = [];
failCallback = [];
resolve = value => {
if (this.status !== PENDING) return;
this.status = FULFILLED;
this.value = value;
while (this.successCallback.length) this.successCallback.shift()()
}
reject = reason => {
if (this.status !== PENDING) return;
this.status = REJECTED;
this.reason = reason;
while (this.failCallback.length) this.failCallback.shift()()
}
then(successCallback, failCallback) {
successCallback = successCallback ? successCallback : value => value;
failCallback = failCallback ? failCallback : reason => { throw reason }
let promise2 = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
setTimeout(() => {
try {
let x = successCallback(this.value)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = failCallback(this.reason)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else {
this.successCallback.push(() => {
setTimeout(() => {
try {
let x = successCallback(this.value)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
});
this.failCallback.push(() => {
setTimeout(() => {
try {
let x = failCallback(this.reason)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
});
}
});
return promise2;
}
}
function resolvePromise(promise2, x, resolve, reject) {
if(promise2 === x){
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof MyPromise) {
x.then(resolve, reject)
} else {
resolve(x)
}
}
module.exports = MyPromise;
const MyPromise = require('./08.1-then方法参数变为可选');
let promise = new MyPromise((resolve, reject) => {
reject('失败')
})
promise
.then()
.then()
.then(value => console.log(value), reason => { console.log(reason) })
Promise.all 方法的实现
- 用来解决异步并发问题,他允许我们按照异步代码调用的顺序,得到异步代码执行的结果
- all方法是一个静态方法,所以需要再类当中定义一个all方法,all方法前需要加上static关键字
- 接受一个数组作为参数,数组可以填入任何值,包括普通值和promise对象
- 数组当中值得顺序,一定是我们得到结果的顺序
- 返回值也是一个promise对象,所以我们可以在后边链式调用then方法
- 所有的promise状态都是成功才是成功,有一个失败就为失败
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
constructor(executor) {
try {
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e);
}
}
status = PENDING;
value = undefined;
reason = undefined;
successCallback = [];
failCallback = [];
resolve = value => {
if (this.status !== PENDING) return;
this.status = FULFILLED;
this.value = value;
while (this.successCallback.length) this.successCallback.shift()()
}
reject = reason => {
if (this.status !== PENDING) return;
this.status = REJECTED;
this.reason = reason;
while (this.failCallback.length) this.failCallback.shift()()
}
then(successCallback, failCallback) {
successCallback = successCallback ? successCallback : value => value;
failCallback = failCallback ? failCallback : reason => { throw reason }
let promise2 = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
setTimeout(() => {
try {
let x = successCallback(this.value)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = failCallback(this.reason)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else {
this.successCallback.push(() => {
setTimeout(() => {
try {
let x = successCallback(this.value)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
});
this.failCallback.push(() => {
setTimeout(() => {
try {
let x = failCallback(this.reason)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
});
}
});
return promise2;
}
static all(array) {
let result = []
let index = 0
return new MyPromise((resolve, reject) => {
function addData(key, value) {
result[key] = value;
index++;
if (index === array.length) {
resolve(result)
}
}
for (let i = 0; i < array.length; i++) {
let current = array[i]
if (current instanceof MyPromise) {
current.then(value => addData(i, value), reason => reject(reason))
} else {
addData(i, array[i])
}
}
})
}
}
function resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof MyPromise) {
x.then(resolve, reject)
} else {
resolve(x)
}
}
module.exports = MyPromise;
const MyPromise = require('./10.1-Promise.All方法的实现');
function p1() {
return new MyPromise(function (resolve, reject) {
setTimeout(function () {
resolve('p1')
}, 2000)
})
}
function p2() {
return new MyPromise(function (resolve, reject) {
resolve('p2')
})
}
MyPromise.all(['a', 'b', p1(), p2(), 'c']).then(result => console.log(result))
function p1() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve('p1')
}, 2000)
})
}
function p2() {
return new Promise(function (resolve, reject) {
resolve('p2')
})
}
promise.all(['a', 'b', p1(), p2(), 'c']).then(function (result) {
console.log(result)
});
Promise.resolve 方法的实现
- 将给定的值转换为Promise对象
- 返回值是一个Promise对象
- 返回的Promise对象当中会包裹给定的值
- resolve内部会判断传入的值是普通值还是promise对象
- 普通值 — 处理成promise对象
- promise对象 — 原封不动的将promise对象作为resolve的返回值
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
constructor(executor) {
try {
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e);
}
}
status = PENDING;
value = undefined;
reason = undefined;
successCallback = [];
failCallback = [];
resolve = value => {
if (this.status !== PENDING) return;
this.status = FULFILLED;
this.value = value;
while (this.successCallback.length) this.successCallback.shift()()
}
reject = reason => {
if (this.status !== PENDING) return;
this.status = REJECTED;
this.reason = reason;
while (this.failCallback.length) this.failCallback.shift()()
}
then(successCallback, failCallback) {
successCallback = successCallback ? successCallback : value => value;
failCallback = failCallback ? failCallback : reason => { throw reason }
let promise2 = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
setTimeout(() => {
try {
let x = successCallback(this.value)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = failCallback(this.reason)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else {
this.successCallback.push(() => {
setTimeout(() => {
try {
let x = successCallback(this.value)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
});
this.failCallback.push(() => {
setTimeout(() => {
try {
let x = failCallback(this.reason)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
});
}
});
return promise2;
}
static all (array) {
let result = [];
let index = 0;
return new MyPromise((resolve, reject) => {
function addData(key, value) {
result[key] = value;
index++;
if (index === array.length) {
resolve(result)
}
}
for (let i = 0; i < array.length; i++) {
let current = array[i]
if (current instanceof MyPromise) {
current.then(value => addData(i, value), reason => reject(reason))
} else {
addData(i, array[i])
}
}
})
}
static resolve (value) {
if (value instanceof MyPromise) return value;
return new MyPromise(resolve => resolve(value))
}
}
function resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof MyPromise) {
x.then(resolve, reject)
} else {
resolve(x)
}
}
module.exports = MyPromise;
const MyPromise = require('./12.1-Promise.resolve方法的实现');
function p1() {
return new MyPromise(function (resolve, reject) {
setTimeout(function () {
resolve('p1')
}, 2000)
})
}
function p2() {
return new MyPromise(function (resolve, reject) {
resolve('p2')
})
}
MyPromise.resolve(100).then(value => console.log(value))
MyPromise.resolve(p1()).then(value => console.log(value))
function p1() {
return new Promise(function (resolve, reject) {
resolve('hello')
})
}
Promise.resolve(10).then(value => console.log(value))
Promise.resolve(p1()).then(value => console.log(value))
finally 方法的实现
- 两个特点
- 无论当前Promise对象的状态最终成功还是失败,finally方法当中回调函数始终都会被都会被执行一次
- 在finally方法的后边,我们可以链式调用then方法拿到当前promise对象中返回的结果
- finally不是一个静态方法,需要定义在MyPromise对象当中的类的原型对象身上
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
constructor(executor) {
try {
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e);
}
}
status = PENDING;
value = undefined;
reason = undefined;
successCallback = [];
failCallback = [];
resolve = value => {
if (this.status !== PENDING) return;
this.status = FULFILLED;
this.value = value;
while (this.successCallback.length) this.successCallback.shift()()
}
reject = reason => {
if (this.status !== PENDING) return;
this.status = REJECTED;
this.reason = reason;
while (this.failCallback.length) this.failCallback.shift()()
}
then(successCallback, failCallback) {
successCallback = successCallback ? successCallback : value => value;
failCallback = failCallback ? failCallback : reason => { throw reason }
let promise2 = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
setTimeout(() => {
try {
let x = successCallback(this.value)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = failCallback(this.reason)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else {
this.successCallback.push(() => {
setTimeout(() => {
try {
let x = successCallback(this.value)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
});
this.failCallback.push(() => {
setTimeout(() => {
try {
let x = failCallback(this.reason)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
});
}
});
return promise2;
}
finally (callback) {
return this.then(value => {
return MyPromise.resolve(callback()).then(() => value);
}, reason => {
return MyPromise.resolve(callback()).then(() => {throw reason});
})
}
static all (array) {
let result = [];
let index = 0;
return new MyPromise((resolve, reject) => {
function addData(key, value) {
result[key] = value;
index++;
if (index === array.length) {
resolve(result)
}
}
for (let i = 0; i < array.length; i++) {
let current = array[i]
if (current instanceof MyPromise) {
current.then(value => addData(i, value), reason => reject(reason))
} else {
addData(i, array[i])
}
}
})
}
static resolve (value) {
if (value instanceof MyPromise) return value;
return new MyPromise(resolve => resolve(value))
}
}
function resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof MyPromise) {
x.then(resolve, reject)
} else {
resolve(x)
}
}
module.exports = MyPromise;
const MyPromise = require('./14.1-Promise.finally方法的实现');
function p1() {
return new MyPromise(function (resolve, reject) {
setTimeout(function () {
resolve('p1')
}, 2000)
})
}
function p2() {
return new MyPromise(function (resolve, reject) {
resolve('p2 resolve')
})
}
p2().finally(() => {
console.log('finally')
return p1();
}).then(value => {
console.log(value)
}, reason => {
console.log(reason)
});
function p1() {
return new Promise(function (resolve, reject) {
resolve('hello')
})
}
p1().finally(() => {
console.log('finally')
}).then(value => console.log(value));
catch 方法的实现
- 处理当前promise对象的最终状态为失败这种情况
- 调用then方法的时候可以不传递失败的回调,可以通过catch方法去捕获,从而执行传递到catch的回调函数
- catch的内部去调用then方法,在then方法内部的成功回调的地方传入undefined,在失败的地方传入回调函数
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
constructor(executor) {
try {
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e);
}
}
status = PENDING;
value = undefined;
reason = undefined;
successCallback = [];
failCallback = [];
resolve = value => {
if (this.status !== PENDING) return;
this.status = FULFILLED;
this.value = value;
while (this.successCallback.length) this.successCallback.shift()()
}
reject = reason => {
if (this.status !== PENDING) return;
this.status = REJECTED;
this.reason = reason;
while (this.failCallback.length) this.failCallback.shift()()
}
then(successCallback, failCallback) {
successCallback = successCallback ? successCallback : value => value;
failCallback = failCallback ? failCallback : reason => { throw reason }
let promise2 = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
setTimeout(() => {
try {
let x = successCallback(this.value)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = failCallback(this.reason)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else {
this.successCallback.push(() => {
setTimeout(() => {
try {
let x = successCallback(this.value)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
});
this.failCallback.push(() => {
setTimeout(() => {
try {
let x = failCallback(this.reason)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
});
}
});
return promise2;
}
finally (callback) {
return this.then(value => {
return MyPromise.resolve(callback()).then(() => value);
}, reason => {
return MyPromise.resolve(callback()).then(() => {throw reason});
})
}
catch (fullCallback) {
return this.then(undefined, fullCallback)
}
static all (array) {
let result = [];
let index = 0;
return new MyPromise((resolve, reject) => {
function addData(key, value) {
result[key] = value;
index++;
if (index === array.length) {
resolve(result)
}
}
for (let i = 0; i < array.length; i++) {
let current = array[i]
if (current instanceof MyPromise) {
current.then(value => addData(i, value), reason => reject(reason))
} else {
addData(i, array[i])
}
}
})
}
static resolve (value) {
if (value instanceof MyPromise) return value;
return new MyPromise(resolve => resolve(value))
}
}
function resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof MyPromise) {
x.then(resolve, reject)
} else {
resolve(x)
}
}
module.exports = MyPromise;
const MyPromise = require('./16.1-Promise.catch方法的实现');
function p1() {
return new MyPromise(function (resolve, reject) {
setTimeout(function () {
resolve('p1')
}, 2000)
})
}
function p2() {
return new MyPromise(function (resolve, reject) {
reject('失败')
})
}
p2()
.then(value => console.log(value))
.catch(reason => console.log(reason))
function p1() {
return new Promise(function (resolve, reject) {
reject('hello')
})
}
p1()
.then(value => console.log(value))
.catch(reason => console.log(reason))