Promise 可以解决回调地狱的问题。
Promise 异步编程的一种解决方案,比传统的解决方案(回调函数)更合理和更强大。
Promise对象有以下两个特点。
(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(resolve已成功)和rejected(已失败)。
(2)一旦状态设定,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了
promise状态:pending(进行中) resolve(成功,已解决) reject(失败,未解决)
pending–>resolve 进行中–>成功
pending–>reject 进行中–>失败
promise原型下面三个常用的方法:
Promise.prototype.then Promise.prototype.catch Promise.prototype.finally
resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步
操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。
Promise.all():用于将多个 Promise 实例,包装成一个新的 Promise 实例,接受一个数组作为参数,只有数组里面的每个状态都变成resolve,则新的 Promise 实例状态才会变成resolve.
Promise.race([promise1,promise2]):竞速函数,当有一个promise对象状态变化了,该对象就会采用和相同的状态,并执行相应函数。**加载多个接口**
执行顺序:
let promise=new Promise((resolve,reject)=>{
主线程:
console.log(1)
异步的:
resolve();
});
promsie.then(()=>{
异步的:
console.log(2);
});
conosle.log(3);//主线程
1,3,2
手写promise
function myPromise() {
//定义三个
const PENDING = "pending";//
const RESOLVED = "resolved";
const REJECTED = "rejected";
function Promise(excutor) {
this.status = PENDING
this.data = undefined
this.callbacks = []
let handle = (status, output, cbMethods) => {
if (this.status !== PENDING) return
this.status = status
//保存value数据
this.data = output
//如果有待执行cb函数,则立即异步执行
if (this.callbacks.length > 0) {
setTimeout(() => {
this.callbacks.forEach(cbObj => {
cbObj[cbMethods](output)
});
}, 0);
}
}
const resolve = (value) => {
handle(RESOLVED, value, 'onResolved')
}
const reject = (reason) => {
handle(REJECTED, reason, 'onRejected')
}
try {
excutor(resolve, reject)
} catch (error) {
reject(error)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
// 判断两个参数是否为函数类型,因为这两个参数是可选参数
onResolved = typeof onResolved === 'function' ? onResolved : value => value
onRejected = typeof onRejected === 'function' ? onRejected : reason => {
console.error(reason);
}
return new Promise((resolve, reject) => {
let handle = (callback) => { //封装方法
try {
const result = callback(this.data)
if (result instanceof Promise) {
result.then(resolve, reject)
} else {
resolve(result)
}
} catch (error) {
reject(error)
}
}
if (this.status === PENDING) {
this.callbacks.push({
onResolved() {
handle(onResolved)
},
onRejected() {
handle(onRejected)
}
})
} else if (this.status === RESOLVED) {
setTimeout(() => {
handle(onResolved)
}, 0);
} else {//'rejected'
setTimeout(() => {
handle(onRejected)
}, 0);
}
});
}
Promise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected)
}
Promise.resolve = function (value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(resolve, reject)
} else {
resolve(value)
}
})
}
Promise.reject = function (reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
Promise.all = function (promiseS) {
const values = new Array(promiseS.length)
let resolvedCount = 0
return new Promise((resolve, reject) => {
promiseS.forEach((p, i) => {
Promise.resolve(p).then(
res => {
resolvedCount++
values[i] = res
if (resolvedCount === promiseS.length) {
resolve(values)
}
},
reason => {
reject(reason)
})
})
})
}
Promise.race = function (promiseS) {
return new Promise((resolve, reject) => {
promiseS.forEach(p => {
Promise.resolve(p).then(
res => {
resolve(p.data)
},
reason => {
reject(p.data)
})
})
})
}
window.Promise = Promise
}
myPromise()