还不知道Promise是啥?
参考文章
js
function Promise(fn) {
this.state = 'pending' // 状态
this.res = undefined // 成功的返回值
this.err = undefined // 失败的返回值
this.fn1Callbacks = []
this.fn2Callbacks = []
const resolve = value => {
setTimeout(() => {
if (this.state === 'pending') {
this.state = 'resolved'
this.value = value
for (let i = 0; i < this.fn1Callbacks.length; i++) {
this.fn1Callbacks[i](value);
}
}
})
}
const reject = error => {
setTimeout(() => {
if (this.state === 'pending') {
this.state = 'rejected'
this.err = error
for (let i = 0; i < this.fn2Callbacks.length; i++) {
this.fn2Callbacks[i](error);
}
}
})
}
try {
fn(resolve, reject)
} catch (error) {
reject(error)
}
}
function resolvePromise(otherPromise, x, resolve, reject) {
if (otherPromise === x) {
return reject(new Error('promise loop'))
}
if (x instanceof Promise) {
x.then(value => {
resolve(value)
}, error => {
reject(error)
})
return
}
if (x instanceof Object || typeof x === 'function') {
try {
const then = x.then
let called
if (typeof then === 'function') {
then.call(x, y => {
if (called) {
return
}
called = true
return resolvePromise(otherPromise, y, resolve, reject)
}, r => {
if (called) {
return
}
called = true
return reject(r)
})
} else {
resolve(x)
}
} catch (error) {
if (called) {
return
}
reject(error)
}
} else {
resolve(x)
}
}
Promise.prototype.then = function (fn1, fn2) {
const _this = this
let otherpro
fn1 = typeof fn1 === 'function' ? fn1 : function (value) { }
fn2 = typeof fn2 === 'function' ? fn2 : function (error) { }
if (this.state === 'resolved') {
return otherpro = new Promise((resolve, reject) => {
setTimeout(() => {
try {
const x = fn1(_this.value)
resolvePromise(otherpro, x, resolve, reject)
} catch (error) {
reject(error)
}
})
})
} else if (this.state === 'rejected') {
return otherpro = new Promise(function (resolve, reject) {
setTimeout(() => {
try {
const x = fn2(_this.err)
// reject(x)
resolvePromise(otherpro, x, resolve, reject)
} catch (error) {
reject(error)
}
})
})
} else {
return otherpro = new Promise(function (resolve, reject) {
_this.fn1Callbacks.push(function () {
try {
const x = fn1(_this.value)
// resolve(x)
resolvePromise(otherpro, x, resolve, reject)
} catch (error) {
reject(error)
}
})
_this.fn2Callbacks.push(function () {
try {
const x = fn2(_this.err)
// reject(x)
resolvePromise(otherpro, x, resolve, reject)
} catch (error) {
reject(error)
}
})
})
}
}
Promise.prototype.catch = function (fn) {
this.then(null, fn)
}
Promise.prototype.finally = function (fn) {
return this.then(res => {
return new Promise(resolve => {
resolve(fn())
}).then(() => {
return res
})
}).catch(err => {
return new Promise(resolve => {
resolve(fn())
}).then(() => {
throw err
})
})
}
Promise.resolve = function (params) {
if (params instanceof Promise) {
return params
}
return new Promise(function (resolve) {
resolve(params)
})
}
Promise.reject = function (err) {
return new Promise(function (resolve, reject) {
reject(err)
})
}
Promise.all = function (promises) {
return new Promise(function (resolve, reject) {
if (!promises || !Array.isArray(promises)) {
reject('promises must be a array')
}
if (promises.length === 0) {
return resolve([])
}
const data = []
let num = 0
promises.forEach(item => {
item.then(res => {
data.push(res)
num++
if (num === promises.length) {
resolve(data)
}
}).catch(err => {
reject(err)
})
})
})
}
Promise.race = function (promises) {
return new Promise(function (resolve, reject) {
if (!promises || !Array.isArray(promises)) {
reject('promises must be a array')
}
if (promises.length === 0) {
return resolve()
}
promises.forEach(item => {
item.then(res => {
data.push(res)
resolve(res)
}).catch(err => {
reject(err)
})
})
})
}
new Promise((resolve, reject) => {
resolve('aaa')
}).then(val => {
console.log(val)
}).finally(val => {
console.log(val)
setTimeout(() => {
console.log(val)
})
})