Comments (1)
具体实现讲解可参考这里
const PENDING = "PENDING";
const RESOLVED = "RESOLVED";
const REJECTED = "REJECTED";
const resolvePromise = (promise2, x, resolve, reject) => {
console.log(promise2);
if (promise2 === x) {
// # 2.3.1 If promise and x refer to the same object, reject promise with a TypeError as the reason.
return reject(
new TypeError("Chaining cycle detected for promise #<Promise>")
);
}
if ((typeof x === "object" && x !== null) || typeof x === "function") {
// 防止多次调用成功和失败
// # 2.3.3.3.3 If both resolvePromise and rejectPromise are called, or multiple calls to the same argument are made, the first call takes precedence, and any further calls are ignored.
let called;
try {
// 取x的then属性,如果是一个函数,认定其为promise
let then = x.then;
if (typeof then === "function") {
// # 2.3.3.3 If then is a function, call it with x as this, first argument resolvePromise, and second argument rejectPromise
then.call(
x,
(y) => {
// # 2.3.3.3.1 If/when resolvePromise is called with a value y, run [[Resolve]](promise, y).
// 采用promise的成功结果将值向下传递
// 这里的y有可能还是一个promise,所以递归调用resolvePromise
if (called) {
return;
}
called = true;
resolvePromise(promise2, y, resolve, reject);
},
(r) => {
// # 2.3.3.3.2 If/when rejectPromise is called with a reason r, reject promise with r
// 采用失败结果向下传递
if (called) {
return;
}
called = true;
reject(r);
}
);
} else {
// 说明x是一个普通对象
resolve(x);
}
} catch (e) {
if (called) {
return;
}
called = true;
reject(e);
}
} else {
// x是一个普通值
// # 2.3.4 If x is not an object or function, fulfill promise with x
resolve(x);
}
};
class Promise {
constructor(executor) {
this.status = "PENDING"; // 默认pending状态
this.value = undefined;
this.reason = undefined;
this.onResolvedCallbacks = [];
this.onRejectedCallbacks = [];
let resolve = (value) => {
if (this.status === PENDING) {
this.value = value;
this.status = RESOLVED;
this.onResolvedCallbacks.forEach((fn) => fn());
}
};
let reject = (reason) => {
if (this.status === PENDING) {
this.reason = reason;
this.status = REJECTED;
this.onRejectedCallbacks.forEach((fn) => fn());
}
};
try {
executor(resolve, reject); // 默认执行器会立即执行
} catch (error) {
reject(e);
}
}
then(onfulfilled, onrejected) {
// onfulfilled onrejected是可选参数
// # 2.2.1 Both onFulfilled and onRejected are optional arguments:
onfulfilled =
typeof onfulfilled === "function" ? onfulfilled : (data) => data;
onrejected =
typeof onrejected === "function"
? onrejected
: (err) => {
throw err;
};
let promise2 = new Promise((resolve, reject) => {
if (this.status === RESOLVED) {
setTimeout(() => {
try {
// # 2.2.2 If onFulfilled is a function:
// # 2.2.2.1 it must be called after promise is fulfilled, with promise’s value as its first argument.
let x = onfulfilled(this.value);
// x可能是普通值 也可能是promise
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
}
if (this.status === REJECTED) {
setTimeout(() => {
try {
// # 2.2.3 If onRejected is a function,
// # 2.2.3.1 it must be called after promise is rejected, with promise’s reason as its first argument.
let x = onrejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
}
if (this.status === PENDING) {
this.onResolvedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onfulfilled(this.value);
// x可能是普通值 也可能是promise
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onrejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
}
});
return promise2;
}
}
// resolve方法
Promise.resolve = function (val) {
return new Promise((resolve, reject) => {
resolve(val);
});
};
// reject方法
Promise.reject = function (val) {
return new Promise((resolve, reject) => {
reject(val);
});
};
// race方法
Promise.race = function (promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(resolve, reject);
}
});
};
// all方法(获取所有的promise,都执行then,把结果放到数组,一起返回)
Promise.defer = Promise.deferred = function () {
let dfd = {};
dfd.promise = new Promise((resolve, reject) => {
dfd.resolve = resolve;
dfd.reject = reject;
});
return dfd;
};
module.exports = Promise;
from fe_interview.
Related Issues (20)
- Vue中v-html会导致哪些问题?
- 如何理解MVVM原理?
- 为什么Vue采用异步渲染? HOT 1
- Vue父子组件生命周期的调用顺序?
- Vue中v-model的实现原理以及如何自定义v-model
- 谈谈你对keep-alive的理解 HOT 2
- 你知道Vue中的computed是怎么实现的吗? HOT 1
- Vue ajax请求放在哪个生命周期中? HOT 2
- 你是怎么理解JavaScript 中的执行上下文和执行栈的? HOT 2
- 说一下js中的词法作用域和动态作用域 HOT 2
- var缺陷以及为什么要引入let和const?
- 谈一下js中的作用域链 HOT 1
- 说一下几种常见算法的时间复杂度 HOT 1
- 说一下浏览器缓存
- es module和commonjs的区别
- for、forEach、map的性能对比
- Webpack热更新的原理
- 简单说下webpack中的文件指纹策略 HOT 1
- 讲一下TCP三次握手、四次挥手过程及原理 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from fe_interview.