Skip to content

Instantly share code, notes, and snippets.

@nexpr
Last active January 16, 2016 12:32
Show Gist options
  • Save nexpr/57ac4ac2d1f0c37a7be8 to your computer and use it in GitHub Desktop.
Save nexpr/57ac4ac2d1f0c37a7be8 to your computer and use it in GitHub Desktop.
自作promiseそれなりには動くはず
function promise(fn){
var self = {
status: "pending",
value: undefined,
nexts: [],
__proto__: promise.prototype
}
function common(value, status){
if(self.status !== "pending") return
self.status = status
self.value = value
self.doNexts()
}
var resolve = value => common(value, "resolved")
var reject = value => common(value, "rejected")
try{
fn(resolve, reject)
}catch(e){
reject(e)
}
return self
}
promise.prototype.then = function(fn){
return this._common(fn, "resolved")
}
promise.prototype.catch = function(fn){
return this._common(fn, "rejected")
}
promise.prototype._common = function(fn, status){
return promise((aa,bb) => {
var f = (value) => {
if(this.status === status){
try{
var result = fn(value)
}catch(e){
return bb(e)
}
if(result && result instanceof promise){
result.then(e => aa(e))
result.catch(e => bb(e))
}else{
aa(result)
}
}else{
this.status === "resolved" ? aa(value) : bb(value)
}
}
if(this.status === "pending"){
this.nexts.push(f)
}else{
f(this.value)
}
})
}
promise.prototype.doNexts = function(){
while(this.nexts.length) this.nexts.shift()(this.value)
}
promise.resolve = () => ({
status: "resolved",
value: undefined,
nexts: [],
__proto__: promise.prototype
})
promise.reject = () => ({
status: "rejected",
value: undefined,
nexts: [],
__proto__: promise.prototype
})
var p = promise((a,b) => setTimeout(a, 1000, 12))
p.then(e => console.log(e))
p.then(e => console.log(e+1))
p.then(e => console.log(e+2))
// 12
// 13
// 14
var p = promise((a,b) => setTimeout(a, 1000, 16))
p.then(e => e / 4).then(e => e + 2).then(e => console.log(e * e))
// 36
var p = promise((a,b) => setTimeout(b, 1000, 16))
p.then(e => console.log(e)).catch(e => console.log(-e))
// -16
promise((a,b) => setTimeout(a, 1000, 1))
.then(e => promise((a,b) => setTimeout(a, 1000, e+1)))
.then(e => console.log(e))
// 2
promise((a,b) => a())
.then(e => promise.reject())
.catch(e => console.log(111))
// 111
promise((a,b) => a(1)).then(e => no_defined_value).catch(e => console.log(e))
// ReferenceError: no_defined_value is not defined(…)
promise((a,b) => no_defined_value).then(e => 1).catch(e => console.log(e))
// ReferenceError: no_defined_value is not defined(…)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment