手写Promise源码,阿里、百度等大厂技术面试题汇总

// 导出

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 #’))

}

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) => {

// throw new Error(‘executor error’)

// resolve(‘成功’)

// reject(‘失败’)

setTimeout(() => {

resolve(‘2000’)

}, 2000)

})

promise.then(value => {

console.log(value)

// throw new Error(‘then error’)

return 123

}, reason => {

// console.log(reason.message)

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 #’))

}

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) => {

// resolve(‘成功’)

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 = [] // 存储Promise对象的结果

let index = 0 // 存储addData()执行次数

// 返回一个Promise对象,传递一个执行器并接受两个参数

return new MyPromise((resolve, reject) => {

/**

  • 将promise的值,放入到数组中

  • 因为内部需要使用resolve()方法,所以将该函数放入到执行器中

  • */

function addData(key, value) {

result[key] = value;

index++;

// 判断数组当中所有内容是否执行完毕

if (index === array.length) {

// 防止for循环结束直接调用resolve()时,有异步操作没执行结束!

resolve(result)

}

}

/**

  • 循环该数组内所有元素并对其进行一个判断,判断该元素是否为Promise对象

  • */

for (let i = 0; i < array.length; i++) {

// 拿到当前值

let current = array[i]

// 判断当前是是否是 MyPromise 下的一个实例

if (current instanceof MyPromise) {

// promise对象

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 #’))

}

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))

// 11-Promise.All方法的实现.html

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) {

// result -> [‘a’, ‘b’, p1(), p2(), ‘c’]

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 #’))

}

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))

// 13-Promise.resolve方法的实现.html

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) {

/**

  • 通过then方法得到当前promise对象的状态

  • 因为finally可以在后边通过链式调用then方法,所以需要返回一个promise对象

  • 刚好then方法的返回值就是promise对象,所以直接返回then即可

  • 因为then方法要得到当前promise对象的一个结果

  • 所以在then方法内需要返回成功的结果和失败的原因

  • */

return this.then(value => {

// callback();

// return value;

/**

  • 借助resolve方法判断callback()的返回值是什么

  • 如果是普通值,就转化为promise对象,然后等待这个promise对象的执行完成

  • 如果是promise对象,继续等待这个promise对象的执行完成

  • 然后再返回value

  • */

return MyPromise.resolve(callback()).then(() => value);

}, reason => {

// callback();

// throw 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 #’))

}

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)

})

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:前端)
img

t) => {

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 #’))

}

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)

})

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-Z6If28r8-1710929533849)]
[外链图片转存中…(img-3185f8e9-1710929533849)]
[外链图片转存中…(img-AjZyh4yk-1710929533849)]
[外链图片转存中…(img-sBlt046H-1710929533850)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:前端)
[外链图片转存中…(img-YCXqFCq9-1710929533850)]

  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值