前端学习9 Promise
promise,是异步操作(读取文件,发起网络请求)的一种解决方案,解决了回调地狱(传统的解决方案)的出现。
1.回调地狱
在异步编程的领域中,回调地狱是一个经常困扰开发者的难题。它的产生源于回调函数的过度嵌套,从而导致代码结构变得错综复杂。当一个回调函数内部嵌套另一个回调函数时,就像是在一个盒子里不断嵌套更小的盒子,层层深入。
例如,假设我们要模拟发送三个异步请求,并且第二个请求依赖于第一个请求结果中的某个特定值作为参数,第三个请求又依赖于第二个请求结果中的某个值作为参数。如果使用传统的回调函数方式,代码可能会呈现出如下的形态:
function fn() {
setTimeout(function () {
console.log("111");
setTimeout(function () {
console.log("222");
setTimeout(function () {
console.log("333");
}, 1000);
}, 2000);
}, 3000);
}
fn();
在这段代码中,setTimeout函数模拟了异步操作,锁着嵌套函数的一层层增加,代码就像一团乱麻,所以我们使用Promise来解决回调地狱这个问题,之后我们会学习最先进的异步方案:async 和 await。
2. promise 对象
Promise对象是一个独立的个体,通过自身的状态来控制异步操作。promise一共有三种状态,每一种状态都代表着异步操作的一个特定阶段:
1.pedding :进行中,Promise处于等待;
2.fulfilled :异步操作已经成功;
3.rejected :异步操作已经失败;
3. Promise 实例
const ps = new Promise(function (resolve,reject) {});
这样就创建了一个Promise实例,Promise接受一个函数类型作为参数,这个函数有接受两个参数resolve,reject。分别表示成功回调(fulfilled)和失败回调(rejected)。
4.Promise 方法
为了更好的控制下一步执行,我们有三个实例方法:then,catch,finally;
4.1 then 方法
then方法一般接受两个参数resolve,reject。
const ps2 = new Promise(function (resolve, reject) {
let number = 9;
if (number >= 10) {
resolve(number);
} else {
reject("number 小于10");
}
});
ps2.then(
function (res) {
console.log(res);
},
function (err) {
console.log(err);
}
);
4.2 catch 方法
then方法支持链式调用,但是then的执行严重依赖上一步的结果,上一步没有结果,那么下一步就不会执行,但是每一步都写reject特别麻烦,所以诞生了catch,then就可以省略reject方法,reject交给catch执行,同时catch还可以捕获resolve的异常。
const ps2 = new Promise(function (resolve, reject) {
let number = 9;
if (number >= 10) {
resolve(number);
} else {
reject("number 小于10");
}
});
ps2
.then(function (res) {})
.catch(function (err) {
console.log(err);
});
4.3 finally 方法
无论成功还是失败都需要执行一些操作,就诞生了 finally。我们可以在这做一些清理工作。
const ps2 = new Promise(function (resolve, reject) {
let number = 9;
if (number >= 10) {
resolve(number);
} else {
reject("number 小于10");
}
});
ps2
.then(function (res) {})
.catch(function (err) {
console.log(err);
})
.finally(function () {
console.log("end");
});
5.then的链式调用
then方法返回的是一个新的Promise实例,也就是promise能链式书写的原因。
const ps = new Promise(function (resolve, reject) {
let number = 10;
if (number >= 10) {
resolve(number);
} else {
reject("number 小于10");
}
});
ps.then(function (res) {
return res * 10;
})
.then(function (res) {
return res + 2;
})
.then(function (res) {
if (res > 100) {
console.log(res);
} else {
console.log("最后结果小于100");
}
});
其中return res * 10;创建一个新的Promise,其状态为fulfilled,并携带结果值 100。 我们来可以返回一个自己创建的Promise对象。
function date() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('相亲了');
// 可以传递一个对象表示相亲的结果
resolve('和最爱的人相亲了');
}, 2000);
});
}
function marry() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('结婚了');
// 传递结婚的相关信息
resolve('和最爱的人结婚了');
}, 1000);
});
}
function baby() {
console.log('出生了');
}
date()
.then(resultFromDate => {
console.log('相亲结果:', resultFromDate);
return marry();
})
.then(resultFromMarry => {
console.log('结婚信息:', resultFromMarry);
baby();
});
5.Promise 原型方法
为了满足更多的业务需要,又诞生了 6 个原型方法 Promise.all()、Promise.allSettled()、Promise.any()、Promise.race()、Promise.reject()、Promise.resolve()。且都会返回一个确定状态的 Promsie 对象。
5.1 Promise.all()
通过数组的形式传入异步操作,所有的异步执行都成功,才执行成功,如果有一个失败了,就执行失败。
Promise.all([ps1, ps2])
.then(function (res) {
console.log("都成功", res);
})
.catch(function (err) {
console.log(err);
});
5.2 Promise.allSettled()
所有执行都有结果了就执行,无论成功还是失败。
Promise.allSettled([ps1, ps2, ps3, ps4]).then(function (res) {
console.log("都返回结果", res);
});
5.3 Promise.any()
任意异步成功了就执行。
Promise.any([ps1, ps2, ps3, ps4]).then(function (res) {
console.log("任意成功", res);
});
5.4 Promise.race()
任意异步成功或失败就执行。
5.5 Promise.reject()
返回一个状态为 rejected 的 Promise 对象。
5.6 Promise.resolve()
会接收 4 种类型的参数:promise 实例 、具有 then 方法的对象、没有 then 方法的对象、不传参
当参数是一个 Promise 实例时,直接返回这个实例。
Promise.resolve(ps1);
当参数是一个具有 then 方法的对象时,将这个对象转为 Promise 对象,并立即执行对象的 then 方法
let obj = {
name: "yqcoder",
then(resolve) {
resolve(this.name);
},
};
Promise.resolve(obj);
当参数是一个没有 then 方法的对象,或者参数不是对象时,就会返回状态为 fulfilled 的新的 Promise 对象,并将参数传入下一个 then。
let obj = {
name: "yqcoder",
};
let ps = Promise.resolve(obj);
ps.then(function (res) {
console.log("结果", res);
});
当不带任何参数时,就会返回一个状态为 fulfilled 的 Promise 对象
Promise.resolve();
#前端学习#