Skip to content

Instantly share code, notes, and snippets.

@cj1128
Created May 18, 2018 02:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cj1128/dfbe872d833afdf4600310aa852ca2b2 to your computer and use it in GitHub Desktop.
Save cj1128/dfbe872d833afdf4600310aa852ca2b2 to your computer and use it in GitHub Desktop.
A simple promise implementation
// pending
// fulfilled
// rejected
class MyPromise {
constructor(executor) {
this.$state = "pending"
this.$res = null
this.$chain = []
const resolve = res => {
if(res && res.then && typeof res.then === "function") {
res.then(resolve, reject)
return
}
if(this.$state !== "pending") return
this.$state = "fulfilled"
this.$res = res
for(let {onFulfilled} of this.$chain) {
onFulfilled && onFulfilled(res)
}
}
const reject = res => {
if(this.$state !== "pending") return
this.$state = "rejected"
this.$res = res
for(let {onRejected} of this.$chain) {
onRejected && onRejected(res)
}
}
executor(resolve, reject)
}
then1(onFulfilled, onRejected) {
if(this.$state === "fulfilled") {
setImmediate(onFulfilled)
} else if(this.$state === "rejected") {
setImmediate(onRejected)
} else {
this.$chain.push({onFulfilled, onRejected})
}
}
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
const _onFulfilled = res => {
resolve(onFulfilled(res))
}
const _onRejected = res => {
reject(onRejected(res))
}
if(this.$state === "fulfilled") {
setImmediate(() => {
_onFulfilled(this.$res)
})
} else if(this.$state === "rejected") {
setImmediate(() => {
_onRejected(this.$res)
})
} else {
this.$chain.push({onFulfilled: _onFulfilled, onRejected: _onRejected})
}
})
}
}
function test1() {
new MyPromise((resolve, reject) => {
setTimeout(function() {
resolve(1)
}, 10)
}).then(console.log)
new MyPromise((resolve, reject) => {
setTimeout(function() {
reject(2)
}, 10)
}).then(null, console.log)
}
function test2() {
new MyPromise((resolve, reject) => {
resolve(1)
})
.then(n => {
console.log(n)
return n + 100
})
.then(n => {
console.log(n)
return n + 200
})
.then(n => {
console.log(n)
return n + 300
})
}
function test3() {
const m = n => new MyPromise((resolve, reject) => {
setTimeout(() => {
console.log("finish m", n)
resolve(n)
}, 10)
})
m(1)
.then(n => {
console.log(n)
return m(2)
})
.then(n => {
console.log(n)
})
}
// test1()
// test2()
// test3()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment