1.提出问题
1-1.问题的产生
- 模拟一次网络请求(异步操作),本想返回成功或失败,结果得到undefined
function req(url) {
setTimeout(() => {
if (url === 'favo.ico') {
return '成功'
} else {
return '失败'
}
}, 3000);
}
const res = req('favo.ico')
console.log(res); // undefined
1-2 最初的解决方法
- 思路:传入两个回调,一个成功一个失败
- 缺点:太过灵活,没有规范,有需要阅读源码、传参不便等问题
function req(url, suc, err) {
setTimeout(() => {
if (url === "favo.ico") {
suc()
} else {
err()
}
}, 3000)
}
function suc() {
console.log("请求成功")
}
function err() {
console.log("请求失败")
}
req("favo.icon", suc, err)
2.promise
2-1.executor立即执行
- newpromise中传递一个回调函数executor立即执行,传入两个参数回调函数resolve/reject
- 执行resolve,回调.then
- 执行reject,回调.catch
const pro = new Promise((resolve, reject) => {
console.log('立即执行');
})
2-2.将最初的解决方法重构
function pro(url) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (url.includes('a')) {
resolve(url)
} else {
reject('err')
}
}, 1000);
})
}
// 第一种写法
pro('aaa').then(res => console.log(res), (rej) => console.log(rej))
// 第二种写法
pro('aaa').then(res => console.log(res)).catch((rej) => console.log(rej))
-
解读:
- newpromise时,传入的executor会被promise自动执行立即执行
- 成功执行resolve,失败执行reject
-
异常处理:
- .then中传入两个回调,第一个resolve(即fullfilled),第二个reject
- .catch捕获
-
好处:
- 统一规范,增强阅读性
- 小幅度减少回调地狱
2-3.promise的状态
-
状态
- pending
- fullfilled(resolve)
- rejected
-
注:状态从待定转为其他,就不能再改变了
const pro = new Promise((res, rej) => {
rej('err')
res('suc')
})
pro.then(res => console.log(res)).catch(rej => console.log(rej))
// err
2-4.resolve的不同值
- 1.只能传一个参数,传一个普通值或对象时,作为then的回调参数
const pro = new Promise((resolve, reject) => {
resolve({ name: "a", age: "b" });
});
pro.then((res) => console.log(res));
// { name: "a", age: "b" }
- 2.promise中传入promise,内部promise决定外部promise的状态
const pro = new Promise((resolve, reject) => {
resolve(
new Promise((resolve, reject) => {
setTimeout(() => {
resolve("aaa"); // aaa
// reject("bbb");
}, 500);
})
);
});
pro.then((res) => console.log(res));
// aaa
- 3.promsie中传入对象,且对象实现了then方法,根据then方法中的调用决定promise状态==>thenable模式
const pro = new Promise((resolve, reject) => {
resolve({
then(res, rej) {
res("成功");
},
});
});
pro.then((res) => console.log(res));
// 成功
2.5.promise的实例方法
2.5.1.then
2.5.1.1.参数
- 两个参数,一个成功回调,一个失败回调
const pro = new Promise((resolve, reject) => {
resolve("aaa");
reject("bbb");
});
pro.then(
(res) => console.log(res, "1"),
(rej) => console.log(rej, "2")
);
- 只捕获错误,第一位写null或''
const pro = new Promise((resolve, reject) => {
reject("bbb");
});
pro.then("", (rej) => console.log(rej, "2"));
2.5.1.2.多次调用,多次输出
2.5.1.3.!then是有返回值的,then的返回值是promise,
未完~