Created
May 8, 2020 07:42
-
-
Save Messiahhh/38abd959665e3b2fa8243afaeec84150 to your computer and use it in GitHub Desktop.
Promise的核心实现
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class Promise { | |
| constructor(executor) { | |
| if (typeof executor !== 'function') { | |
| throw new TypeError("Promise resolver undefined is not a function") | |
| } | |
| this.status = 'pending' | |
| this.value = undefined | |
| this.onResolvedCallback = [] | |
| this.onRejectedCallback = [] | |
| const resolve = (value) => { | |
| if (this.status === 'pending') { | |
| if (value instanceof Promise) { | |
| value.then((data) => { | |
| resolve(data) | |
| }, (reason) => { | |
| reject(reason) | |
| }) | |
| } else { | |
| this.status = 'fulfilled' | |
| this.value = value | |
| this.onResolvedCallback.forEach(callback => callback()) | |
| } | |
| } | |
| } | |
| const reject = (reason) => { | |
| if (this.status === 'pending') { | |
| this.status = 'rejected' | |
| this.value = reason | |
| this.onRejectedCallback.forEach(callback => callback()) | |
| } | |
| } | |
| try { | |
| executor(resolve, reject) | |
| } catch (error) { | |
| reject(error) | |
| } | |
| } | |
| then(onResolve, onReject) { | |
| return new Promise((resolve, reject) => { | |
| if (this.status === 'fulfilled') { | |
| setTimeout(() => { | |
| if (typeof onResolve !== 'function') { | |
| resolve(this.value) | |
| } else { | |
| try { | |
| resolve(onResolve(this.value)) | |
| } catch (error) { | |
| reject(error) | |
| } | |
| } | |
| }) | |
| } | |
| else if (this.status === 'rejected') { | |
| setTimeout(() => { | |
| if (typeof onReject !== 'function') { | |
| reject(this.value) | |
| } else { | |
| try { | |
| resolve(onReject(this.value)) | |
| } catch (error) { | |
| reject(error) | |
| } | |
| } | |
| }) | |
| } | |
| else if (this.status === 'pending') { | |
| this.onResolvedCallback.push(() => { | |
| setTimeout(() => { | |
| if (typeof onResolve !== 'function') { | |
| resolve(this.value) | |
| } else { | |
| try { | |
| resolve(onResolve(this.value)) | |
| } catch (error) { | |
| reject(error) | |
| } | |
| } | |
| }) | |
| }) | |
| this.onRejectedCallback.push(() => { | |
| setTimeout(() => { | |
| if (typeof onReject !== 'function') { | |
| reject(this.value) | |
| } else { | |
| try { | |
| resolve(onReject(this.value)) | |
| } catch (error) { | |
| reject(error) | |
| } | |
| } | |
| }) | |
| }) | |
| } | |
| }) | |
| } | |
| catch(onReject) { | |
| return this.then(null, onReject) | |
| } | |
| static race(promiseArr) { | |
| return new Promise((resolve, reject) => { | |
| promiseArr.forEach((promise) => { | |
| promise.then(value => { | |
| resolve(value) | |
| }, reason => { | |
| reject(reason) | |
| }) | |
| }) | |
| }) | |
| } | |
| static all(promiseArr) { | |
| return new Promise((resolve, reject) => { | |
| let res = [] | |
| let length = promiseArr.length | |
| let count = 0 | |
| promiseArr.forEach((promise, index) => { | |
| promise.then(value => { | |
| res[index] = value | |
| count++ | |
| if (count === length) { | |
| resolve(res) | |
| } | |
| }, (reason) => { | |
| reject(reason) | |
| }) | |
| }) | |
| }) | |
| } | |
| } | |
| // More Infomation / Document | |
| // https://messiahhh.github.io/blog |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment