目录
二. Promise的实例有两个过程,过程的状态PromiseState:
Promise 是异步编程的一种解决方案,比传统的解决方案回调函数和事件更合理和更强大。
所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。
一.Promise的实例有三个状态:
-
待定(pending): 初始状态,既没有被兑现,也没有被拒绝。
-
已兑现(fulfilled): 意味着操作成功完成。
-
已拒绝(rejected): 意味着操作失败
当把一件事情交给promise时,它的状态就是Pending,任务完成了状态就变成了fulfilled 、没有完成失败了就变成了Rejected。
二. Promise的实例有两个过程,过程的状态PromiseState:
pending -> fulfilled : Resolved(已完成)
pending -> rejected:Rejected(已拒绝)
注意:一旦从进行状态变成为其他状态就永远不能更改状态了。
特点:
- 1.将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。流程更加清晰,代码更加优雅。
- 2.Promise对象提供统一的接口,使得控制异步操作更加容易。
缺点:
- 1.无法取消Promise,一旦新建它就会立即执行,无法中途取消。
- 2.如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。
- 3.当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
三.PromiseResult
通过resolve和rejected传入参数时通过打印就会发现PromiseResult的值(值可以是任意数据类型),怎么拿到PromiseResult的值呢
.then中也可以写两个参数 第二个参数是可选的
当状态是pending===》fulfilled状态时会到.then中的第一个参数中的函数 pending===》rejected 回到.then中的第二个参数中的函数
当你不去接收处理的 rejected状态时 会报出Uncaught (in promise) 中文意为未兑现(承诺)
四.resolve不同值的区别
情况一:如果resolve传入一个普通的值或者对象,那么这个值会作为then回调的参数;
情况二:如果resolve中传入的是另外一个Promise,那么这个新Promise会决定原Promise的状态:
情况三:如果resolve中传入的是一个对象,并且这个对象有实现then方法,那么会执行该then方法,并且根据then方法的结果来决定Promise的状态:
五. promise链式调用
在了解链式调用之前 先知道在这个.then函数中返回的是仍一个新的promise对象
p2中的PromiseResult 拿到的返回值是p1.then 函数中的返回值而p1.then函数中 没有返回值 那么返回值就是undefined
p2的PromiseResult = p1.then的返回值
为什么p2拿到的状态是fulfilled呢?不是rejected呢
1. 当.then中返回的不是promise对象时(包括undefined),p2的状态 一直都是fulfilled
2.只有当.then中的 返回的是promsie对象 并且调用的状态是reject()就会失败 rejected
例如下面这个例子就会返回 rejected
既然 p2 也是一个promise对象 我们就可以继续使用.then, 接下来 链式调用就开始了
一直.then .then ~~的写
六,all的用法
与then同级的另一个方法,all方法,该方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后并且执行结果都是成功的时候才执行回调。
function p1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
let num = Math.round(Math.random() * 20)
if (num < 10) {
resolve(`2秒的随机数${num}`);
} else {
reject("2秒的大于10");
}
}, 2000);
});
}
function p2() {
return new Promise((resolve, reject) => {
setTimeout(() => {
let num = Math.round(Math.random() * 20)
if (num < 10) {
resolve(`3秒的随机数${num}`);
} else {
reject("3秒的大于10");
}
}, 3000);
});
}
function promiseAll() {
Promise.all([p1(), p2()]).then(
((res) => {
console.log("全部成功的回调"+res);
})
).catch((err)=>{
console.log("只要返回失败的回调成功的不返回"+err);
})
}
Promise.all来执行,all接收一个数组参数,这组参数为需要执行异步操作的所有方法,里面的值最终都算返回Promise对象。这样,三个异步操作的并行执行的,等到它们都执行完后才会进到then里面。也就是等5秒后才会返回到.then里面。返回值必须是resolve。如果有一个返回reject,那么只返回一个reject,不返回其他成功回调。
这样以后就可以用all并行执行多个异步操作,并且在一个回调中处理所有的返回数据,比如你需要提前准备好所有数据才渲染页面的时候就可以使用all,执行多个异步操作将所有的数据处理好,再去渲染
七,race的用法
all是等所有的异步操作都执行完了再执行then方法,那么race方法就是相反的,谁先执行完成就先执行回调。先执行完的不管是进行了race的成功回调还是失败回调,其余的将不会再进入race的任何回调
function p1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
let num = Math.round(Math.random() * 20)
if (num < 10) {
resolve(`2秒的随机数${num}`);
} else {
reject("2秒的大于10");
}
}, 2000);
});
}
function p2() {
return new Promise((resolve, reject) => {
setTimeout(() => {
let num = Math.round(Math.random() * 20)
if (num < 10) {
resolve(`3秒的随机数${num}`);
} else {
reject("3秒的大于10");
}
}, 3000);
});
}
function promiseRace() {
Promise.race([p1(), p2()]).then(
((res) => {
console.log("成功————"+res);
})
).catch((err)=>{
console.log("失败————"+err);
})
}
因为race只接收第一个返回值只要有返回了就不会再接收其他回调。因为两秒比三秒返回快所以只接收两秒的返回值。
举例:请求一个接口数据,10s内请求完成就展示数据,10s内没有请求完成就提示请求失败
//请求某个table数据
function p1(){
return new Promise((resolve, reject) => {
//去后台请求数据
resolve(res);
});
}
//延时函数,用于给请求计时 10s
function timeout(){
return new Promise((resolve, reject) => {
setTimeout(() => {
reject('请求超时');
}, 10000);
});
}
Promise.race([p1(), timeout()]).then((data) =>{
//进行成功回调处理
console.log(data);
}).catch((err) => {
// 失败回调处理
console.log(err);
});