这是我们希望与promise 一起使用的示例程序;注意小写p -
const delay = ms =>
new promise(r => setTimeout(r, ms))
const roll = n =>
{ console.log("rolling...")
return delay(1000)
.then(_ => Math.ceil(Math.random() * n))
.then(x => { console.log(x); return x })
}
const main = _ =>
roll(20).then(x =>
roll(20).then(y =>
roll(20).then(z =>
{ console.log("three rolls:", x, y, z)
return [x,y,z]
}
)
)
)
main()
.then(([x,y,z]) => x + y + z)
.then(sum => console.log("sum:", sum))
.catch(console.error)
rolling...
12
rolling...
18
rolling...
15
three rolls: 12 18 15
sum: 45
正如其他人评论的那样,您的代码中有很多需要修复的地方。但是不要难过,因为 Promise 并不是特别容易实现。这是我对promise 的第一张草图。注意value、resolved、rejected 是构造函数的参数,但它们应该是私有的。这可以使用多种技术来完成,但为了简单起见,我暂时保持这种方式。调用者只打算传递第一个参数,exec -
class promise
{ constructor(exec, value, resolved = false, rejected = false)
{ this.value = value
this.resolved = resolved
this.rejected = rejected
this.callback = []
if (this.resolved || this.rejected) return
exec(x => this.resolve(x), e => this.reject(e))
}
resolve(value)
{ if (this.resolved || this.rejected) return
let p = promise.resolve(value)
for (const [ifResolved, ifRejected] of this.callback)
p = p.then(ifResolved, ifRejected)
Object.assign(this, p)
}
reject(value)
{ if (this.resolved || this.rejected) return
let p = promise.reject(value)
for (const [ifResolved, ifRejected] of this.callback)
p = p.then(ifResolved, ifRejected)
Object.assign(this, p)
}
then(ifResolved, ifRejected = promise.reject)
{ if (this.resolved)
{ try
{ return promise.resolve(ifResolved(this.value)) }
catch (err)
{ return promise.reject(err) }
}
else if (this.rejected)
{ try
{ return promise.resolve(ifRejected(this.value)) }
catch (err)
{ return promise.reject(err) }
}
else
{ this.callback.push([ifResolved, ifRejected])
return this
}
}
catch(ifRejected)
{ return this.then(value => value, ifRejected) }
static resolve(value)
{ return (value instanceof promise)
? value
: new promise(_ => {}, value, true, false)
}
static reject(value)
{ return (value instanceof promise)
? value
: new promise(_ => {}, value, false, true)
}
}
与 Promise 一样,只有 p.then、p.catch 应该可用于 promise 对象。我们应该阻止用户直接调用p.resolve 或p.reject,但是现在它可以很容易地看到事情是如何工作的。类函数promise.resolve 和promise.reject 类似于Promise.resolve 和Promise.reject。
展开下面的sn-p,在自己的浏览器中验证结果-
class promise
{ constructor(exec, value, resolved = false, rejected = false)
{ this.value = value
this.resolved = resolved
this.rejected = rejected
this.callback = []
if (this.resolved || this.rejected) return
exec(x => this.resolve(x), e => this.reject(e))
}
resolve(value)
{ if (this.resolved || this.rejected) return
let p = promise.resolve(value)
for (const [ifResolved, ifRejected] of this.callback)
p = p.then(ifResolved, ifRejected)
Object.assign(this, p)
}
reject(value)
{ if (this.resolved || this.rejected) return
let p = promise.reject(value)
for (const [ifResolved, ifRejected] of this.callback)
p = p.then(ifResolved, ifRejected)
Object.assign(this, p)
}
then(ifResolved, ifRejected = promise.reject)
{ if (this.resolved)
{ try
{ return promise.resolve(ifResolved(this.value)) }
catch (err)
{ return promise.reject(err) }
}
else if (this.rejected)
{ try
{ return promise.resolve(ifRejected(this.value)) }
catch (err)
{ return promise.reject(err) }
}
else
{ this.callback.push([ifResolved, ifRejected])
return this
}
}
catch(ifRejected)
{ return this.then(value => value, ifRejected) }
static resolve(value)
{ return (value instanceof promise)
? value
: new promise(_ => {}, value, true, false)
}
static reject(value)
{ return (value instanceof promise)
? value
: new promise(_ => {}, value, false, true)
}
}
const delay = ms =>
new promise(r => setTimeout(r, ms))
const roll = n =>
{ console.log("rolling...")
return delay(1000)
.then(_ => Math.ceil(Math.random() * n))
.then(x => { console.log(x); return x })
}
const main = _ =>
roll(20).then(x =>
roll(20).then(y =>
roll(20).then(z =>
{ console.log("three rolls:", x, y, z)
return [x,y,z]
}
)
)
)
main()
.then(([x,y,z]) => x + y + z)
.then(sum => console.log("sum:", sum))
.catch(console.error)
我明天会回来添加一个示例来演示错误并回答任何问题(如果有的话)。