一、Promise 自定义封装
## 1. 初始结构搭建
```html
<script>
let p = new Promise((resolve, reject) => {
resolve('OK')
})
p.then(value => {
console.log(value);
}, reason => {
console.warn(reason);
})
</script>
function Promise(executor) {
}
Promise.prototype.then = function (onResolved, onRejected) {
}
2. resolve 与 reject 结构搭建
function Promise(executor) {
function resolve(data) {
}
function reject(data) {
}
executor(resolve, reject)
}
Promise.prototype.then = function (onResolved, onRejected) {
}
3. resolve 与 reject 代码实现
<script>
let p = new Promise((resolve, reject) => {
resolve('OK')
})
console.log(p);
p.then(value => {
console.log(value);
}, reason => {
console.warn(reason);
})
script>
function Promise(executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
const self = this
function resolve(data) {
self.PromiseState = 'fulfilled'
self.PromiseResult = data
}
function reject(data) {
self.PromiseState = 'rejected'
self.PromiseResult = data
}
executor(resolve, reject)
}
Promise.prototype.then = function (onResolved, onRejected) {
}
4. throw 抛出异常改变状态
<script>
let p = new Promise((resolve, reject) => {
throw new Error('error')
})
console.log(p);
p.then(value => {
console.log(value);
}, reason => {
console.warn(reason);
})
script>
function Promise(executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
const self = this
function resolve(data) {
self.PromiseState = 'fulfilled'
self.PromiseResult = data
}
function reject(data) {
self.PromiseState = 'rejected'
self.PromiseResult = data
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
}
5. Promise 对象只能修改一次
<script>
let p = new Promise((resolve, reject) => {
resolve('OK')
reject('error')
})
console.log(p);
p.then(value => {
console.log(value);
}, reason => {
console.warn(reason);
})
script>
function Promise(executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
const self = this
function resolve(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'fulfilled'
self.PromiseResult = data
}
function reject(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'rejected'
self.PromiseResult = data
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
}
6. then 方法执行回调
<script>
let p = new Promise((resolve, reject) => {
reject('error')
})
console.log(p);
p.then(value => {
console.log(value);
}, reason => {
console.warn(reason);
})
script>
function Promise(executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
const self = this
function resolve(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'fulfilled'
self.PromiseResult = data
}
function reject(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'rejected'
self.PromiseResult = data
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
if (this.PromiseState === 'fulfilled') {
onResolved(this.PromiseResult)
}
if (this.PromiseState === 'rejected') {
onRejected(this.PromiseResult)
}
}
7. 异步任务回调的执行
<script>
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK')
}, 1000);
})
p.then(value => {
console.log(value);
}, reason => {
console.warn(reason);
})
console.log(p);
script>
function Promise(executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
this.callbacks = {}
const self = this
function resolve(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'fulfilled'
self.PromiseResult = data
if (self.callbacks.onResolved) {
self.callbacks.onResolved(data)
}
}
function reject(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'rejected'
self.PromiseResult = data
if (self.callbacks.onRejected) {
self.callbacks.onRejected(data)
}
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
if (this.PromiseState === 'fulfilled') {
onResolved(this.PromiseResult)
}
if (this.PromiseState === 'rejected') {
onRejected(this.PromiseResult)
}
if (this.PromiseState === 'pending') {
this.callbacks = {
onResolved: onResolved,
onRejected: onRejected
}
}
}
8. 指定多个回调的实现
<script>
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK')
}, 1000);
})
p.then(value => {
console.log(value);
}, reason => {
console.warn(reason);
})
p.then(value => {
alert(value);
}, reason => {
console.warn(reason);
})
console.log(p);
script>
function Promise(executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
this.callbacks = []
const self = this
function resolve(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'fulfilled'
self.PromiseResult = data
self.callbacks.forEach(item => {
item.onResolved(data)
})
}
function reject(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'rejected'
self.PromiseResult = data
self.callbacks.forEach(item => {
item.onRejected(data)
})
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
if (this.PromiseState === 'fulfilled') {
onResolved(this.PromiseResult)
}
if (this.PromiseState === 'rejected') {
onRejected(this.PromiseResult)
}
if (this.PromiseState === 'pending') {
this.callbacks.push({
onResolved: onResolved,
onRejected: onRejected
})
}
}
9. 同步修改状态 then 方法结果返回
<script>
let p = new Promise((resolve, reject) => {
resolve('OK')
})
let res = p.then(value => {
console.log(value);
return new Promise((resolve, reject) => {
reject('error')
})
}, reason => {
console.warn(reason);
})
console.log(res);
script>
function Promise(executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
this.callbacks = []
const self = this
function resolve(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'fulfilled'
self.PromiseResult = data
self.callbacks.forEach(item => {
item.onResolved(data)
})
}
function reject(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'rejected'
self.PromiseResult = data
self.callbacks.forEach(item => {
item.onRejected(data)
})
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
return new Promise((resolve, reject) => {
if (this.PromiseState === 'fulfilled') {
try {
let result = onResolved(this.PromiseResult)
if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(result)
}
} catch (error) {
reject(error)
}
}
if (this.PromiseState === 'rejected') {
onRejected(this.PromiseResult)
}
if (this.PromiseState === 'pending') {
this.callbacks.push({
onResolved: onResolved,
onRejected: onRejected
})
}
})
}
10. 异步修改状态 then 方法结果返回
<script>
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK')
}, 1000);
})
let res = p.then(value => {
console.log(value);
return value
}, reason => {
console.warn(reason);
})
console.log(res);
script>
function Promise(executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
this.callbacks = []
const self = this
function resolve(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'fulfilled'
self.PromiseResult = data
self.callbacks.forEach(item => {
item.onResolved(data)
})
}
function reject(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'rejected'
self.PromiseResult = data
self.callbacks.forEach(item => {
item.onRejected(data)
})
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
const self = this
return new Promise((resolve, reject) => {
if (this.PromiseState === 'fulfilled') {
try {
let result = onResolved(this.PromiseResult)
if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(result)
}
} catch (error) {
reject(error)
}
}
if (this.PromiseState === 'rejected') {
onRejected(this.PromiseResult)
}
if (this.PromiseState === 'pending') {
this.callbacks.push({
onResolved: function () {
try {
let result = onResolved(self.PromiseResult)
if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
reject(result)
}
} catch (error) {
reject(error)
}
},
onRejected: function () {
try {
let result = onRejected(self.PromiseResult)
if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
reject(result)
}
} catch (error) {
reject(error)
}
}
})
}
})
}
11. then 方法完善与优化
function Promise(executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
this.callbacks = []
const self = this
function resolve(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'fulfilled'
self.PromiseResult = data
self.callbacks.forEach(item => {
item.onResolved(data)
})
}
function reject(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'rejected'
self.PromiseResult = data
self.callbacks.forEach(item => {
item.onRejected(data)
})
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
const self = this
return new Promise((resolve, reject) => {
function callback(type) {
try {
let result = type(self.PromiseResult)
if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(result)
}
} catch (error) {
reject(error)
}
}
if (this.PromiseState === 'fulfilled') {
callback(onResolved)
}
if (this.PromiseState === 'rejected') {
callback(onRejected)
}
if (this.PromiseState === 'pending') {
this.callbacks.push({
onResolved: function () {
callback(onResolved)
},
onRejected: function () {
callback(onRejected)
}
})
}
})
}