这是我参与「第四届青训营 」笔记创作活动的的第8天
1 Promise的使用(19)
1.1 什么是Promise
-
我们确实可以请求函数得到的结果后,获取对应的回调,但是存在两个主要的问题:
- 我们需要自己来设计回调函数、回调函数的名称、回调函数的使用等;
- 对于不同的人、不同的框架设计出来的方案是不同的。那么我们必须去看别人的源码或文档,以便理解怎么使用;
-
Promise的API
-
Promise是一个类,可以翻译成承诺、期约;
-
当我们需要给予调用者一个期约:待会儿我会给你回调数据时,就可以创建一个Promise对象;
-
再通过new创建Promise对象时,我们需要传入一个回调函数,我们称之为executor
- 这个回调函数会被立即执行,并且给传入另外两个回调函数resolve、reject;
- 当我们调用resolve回调函数时,会执行Promise对象的then方法传入的回调函数;
- 当我们调用reject回调函数时,会执行Promise对象的catch方法传入的回调函数;
-
-
//传入的这个函数,被称为executor 它会被立即执行 //传入两个回调函数 //->resolve:回调函数,在成功时,回调resolve函数 //->reject:回调函数,在失败时,回调reject函数 const promise = new Promise((resolve, reject) => { console.log("Promise传入的函数被执行了"); resolve("success message"); }) //在外面拿到的promies对象 //在里面执行resolve后,外面的then方法会执行 promise.then(() => { }) //在里面执行reject后,外面catch会执行 promise.catch(() => { }) //合并写法 可以传递参数 promise.then((res) => { //成功 相当于then //可以接收resolve传递的数据 console.log(res); },() => { //与上面类似,也可传递参数 //失败 相当于catch }) -
什么是回调函数
//钩子函数:hook 将函数传进来调用 function foo(fn){ fn(); } foo(() => { });1.2 Promise的三种状态
-
new Promise((resolve,reject) => { //给Promise划分状态 这个地方属于executor //在此阶段,Promise的状态为pending(悬而未决) resolve(); }).then(res => { //Promise中调用resolve回到此阶段 //这个阶段被称为 fulfilled/resolved(固定 已敲定) },err => { //Promise中调用reject回到此阶段 //这个阶段被称为rejected(已拒绝) }) -
上面Promise使用过程中,我们可以将它划分为三个状态:
-
待定(pending):初始状态,既没有兑现,也没有被拒绝;
当执行executor中的代码时,处于该状态;
-
已兑现(fulfilled):意味着操作成功完成;
执行resolve时,处于该状态;
-
已拒绝(rejected):意味着操作失败;
执行了reject时,处于该状态;
-
1.3 Promise的resolve参数
-
/**resolve(参数) * 1>普通的值或者对象; * 2>传入一个Promise;那么当前Promise的状态由传入Promise来决定 * 3>传入一个对象,并且这个对象实现了then方法(并且这个对象实现了thenable接口) * 那么也会执行该then方法,并且由该then方法决定后续状态 */ //传入Promise对象 const newPromise = new Promise((resolve,reject) =>{ //这里是什么状态 下面就执行相应的函数 reject(123); }) new Promise((resolve,reject) => { //resolve("resolve message");(1) //2 resolve(newPromise); }).then(res => { console.log("res:",res); },err => { console.log("err:",err); }) //传入一个对象,这个对象有then方法 new Promise((resolve,reject) => { const obj = { //then方法会自动执行,resolve和reject也会自动传递进来 then: function(resolve,reject){ //在这里决定接下来的状态 reject("reject message"); } } //会执行reject方法 resolve(obj); }).then(res => { console.log("res:",res); },err => { console.log("err:",err); })1.4 Promise的对象方法then
-
then方法是Promise对象上的一个方法:它其实是放在Promise的原型上的Promise.prototype.then
//对象上的方法,需要先创建一个对象,在这个对象上调用 const promise = new Promise(); promise.then(); //类方法,不用创建对象直接访问的方法叫做类方法 Promise.all(); class Promise { //对象方法 then(){}; //类方法 static all(){}; } -
同一个Promise可以被多次调用then方法,当我们resolve方法被回调时,所有的then方法传入的回调函数都会被调用
console.log(Object.getOwnPropertyDescriptors(Promise.prototype)); //finally、catch、then、constructor const newPromise = new Promise((resolve,reject) =>{ //下面then方法里传递的回调函数会在这里执行resolve的时候被回调 resolve("hhh"); }) //newPromise.then(callback) //同一个Promise可以被多次调用then方法 当我们resolve方法被回调时,所有的then方法传入的回调函数都会被调用 //输出 res:hhh res1:hhh res2:hhh newPromise.then((res) => { console.log("res:",res); }) newPromise.then((res) => { console.log("res1:",res); }) newPromise.then((res) => { console.log("res2:",res); })-
then方法传入的回调函数是可以有返回值的,它的返回值是Promise
-
(1) 如果我们返回值是一个普通值,那么这个普通值被作为一个新的Promise的resolve值
const newPromise = new Promise((resolve,reject) =>{ resolve("hhh"); }) newPromise.then((res) => { return "aaaa"; }) //上面的代码底层相当于 newPromise.then((res) => { return new Promise((resolve,reject) => { resolve("aaaa"); }) }) //Promise的链式调用 能链式调用的原因是会产生新的Promise newPromise.then((res) => { return "aaaa"; }).then(res => { //这里对应的是第二次new出来Promise的then方法 与上面的then方法不是同一个Promise的then方法 不会同时触发 //输出res aaaa console.log("res",res); return "bbbb" }).then(res => { }) -
(2)如果我们返回的是一个Promise
promise.then(res => { //返回值是一个Promise 会作为新的Promise的resovle的值 //相当于往resolve里传递一个Promise参数 (上面已经提到)名 return new Promise((resolve,reject) => { setTimeout(() => { resolve(111); },3000); }) }).then(res => { //3s后打印res 111 console.log("res",res); }) -
promise.then(res => { const obj = { then:function(resolve,reject){ resolve(2222); } } return obj; //这里返回的是一个新的Promise }).then(res => { //res:2222 console.log("res:",res); })
-