前言
Promise对于前端来说一点都不陌生,主要是用来异步操作。一句话很经典---支持链式调用,解决回调地狱问题。
基本使用
重要的概念
Promise 对象代表一个异步操作,有三种状态,pending进行中,fulfilled(resolved)已成功,rejected 已失败,只有异步操作的结果,才可以决定当前是哪一种状态。
一旦状态改变,就不会再变,Pomise 对象状态改变只有两种可能,从 pending 改到fulfilled 或者从 pending 改到 rejected。
promise方法接受两个参数,第一个是参数是resolve,作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;第二个参数是reject,作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
Promise对象身上有 .then()方法,第一个参数为成功时的回调,第二个方法为失败时的回调。Promise的构造函数是同步执行的。
const promise = new Promise((res, rej) => {
//包裹一个异步的操作(计时器、请求、数据库、读取文件),成功resolve(),失败reject()
setTimeout(() => {
rej("错误")
}, 1000)
})
//.then()方法可以执行成功和失败的回调
promise.then((val) => {
console.log(val);
}, (err) => {
console.log(err); //错误
})
当然也可以直接执行失败的回调
const promise = new Promise((res, rej) => {
//包裹一个异步的操作(计时器、请求、数据库、读取文件),成功resolve(),失败reject()
setTimeout(() => {
rej("错误")
}, 1000)
})
// .catch()方法只能执行失败的回调
promise.catch((err) => {
console.log(err); //错误
})
Promise.resolve()
- 如果传入参数为非Promise类型的对象,则返回的结果为成功promise对象,成功的参数就是传入的参数
let promise = Promise.resolve(1);
promise.then((val) => {
console.log(val); // 1
})
- 如果传入参数为Promise类型的对象,则参数为传入Promise对象成功或失败的结果
let promise = Promise.resolve(new Promise((res, rej) => {
setTimeout(() => {
res('成功')
}, 2000)
}))
promise.then((val) => {
console.log(val); //成功
}).catch((err) => {
console.log(err);
})
Promise.reject()
- 不管传入的是什么,都是执行失败的回调,传入的是什么,失败返回的参数就是什么
let promise = Promise.reject(1);
promise.catch((val) => {
console.log(val); //1
})
let promise1 = Promise.reject(new Promise((res, rej) => {
res(312)
}))
promise1.catch((val) => {
console.log(val); //Promise { 312 }
})
Promise.all()
常用的地方是可以用来并发请求
- 参数为Promise对象数组
- 当传入参数的Promise全都成功,返回结果为成功的Promise对象数组,有一个或多个失败,返回结果为第一个失败的Promise传出的参数
let promise = new Promise((res, rej) => {
setTimeout(() => {
res(1)
},1000)
})
let promise1 = new Promise((res, rej) => {
setTimeout(() => {
res(2)
},1000)
})
let all = Promise.all([promise, promise1])
all.then((val) => {
console.log(val); //[1,2]
})
let promise = new Promise((res, rej) => {
setTimeout(() => {
rej(1)
},1000)
})
let promise1 = new Promise((res, rej) => {
setTimeout(() => {
rej(2)
},1000)
})
let all = Promise.all([promise, promise1])
all.then((val) => {
console.log(val);
}).catch((err) => {
console.log(err); // 1
})
Promise.race()
- 参数Promise对象数组
- 返回一个新的Promise对象,为第一个完成Promise状态,不管失败还是成功。
let promise = new Promise((res, rej) => {
setTimeout(() => {
res(1)
}, 100)
})
let promise1 = new Promise((res, rej) => {
setTimeout(() => {
rej(2)
}, 1000)
})
let race = Promise.race([promise, promise1])
race.then((val) => {
console.log(val); //1
}).catch((err) => {
console.log(err);
})
Promise的链式调用
这就要说一下then()方法的返回结果是什么
- 如果then()方法返回的结果是非Pomise对象,那么执行的是成功的回调,参数为then()方法返回的结果
- 如果then()方法返回是结果是Pomise对象,那么返回的Pomise对象状态决定了then()方法的状态,返回的Pomise的结果就是then()方法的结果
function promise() {
return new Promise((resolve, reject) => {
resolve("A");
})
}
promise().then(
data => {
console.log(data); //A
var B = new Promise((resolve, reject) => {
resolve("B");
})
return B;
}
).then((data) => {
console.log(data); //B
}
).then((data) => {
console.log(data); //undefined
})
当链中有执行失败的结构,抛出了一个错误的异常;所以不会走then;而是直接走catch;,也可以叫异常穿透
function promise() {
return new Promise((resolve, reject) => {
resolve("A");
})
}
promise().then(
data => {
console.log(data); //A
var B = new Promise((resolve, reject) => {
reject("B");
})
return B;
}
).then((data) => {
console.log(data);
}).then((data) => {
console.log(data);
}).catch((err) => {
console.log(err); //B
})
中断Promise链
- 有且只有一种方式去中断Promise;让Promise的状态是padding
let promise = new Promise((res, rej) => {
setTimeout(() => {
res(1)
}, 1000)
})
promise.then((val) => {
console.log(val); //1
//中断
return new Promise(() => { })
}).then((val1) => {
console.log(val1)
}).catch((err) => {
console.log(err);
})