mirror of https://github.com/qianguyihao/Web.git
update: Promise中,then() 方法的返回值
This commit is contained in:
parent
c4621ae2f7
commit
2dbce6df1c
|
|
@ -205,9 +205,9 @@ Promise是一个类,通过 `new Promise()` 进行**实例化**,构造出一
|
|||
|
||||
2、`then()`方法的括号里面有两个参数,分别代表两个回调函数 **onFulfilled** 和 **onRejected**,这两个函数一直处于**监听状态**:
|
||||
|
||||
- 参数1:如果 promise 的状态为 fulfilled(意思是:任务执行成功),则触发 onFulfilled 函数的执行。
|
||||
- 参数1:**成功的回调函数**。如果 Promise 的状态为 fulfilled(意思是:任务执行成功),则触发 onFulfilled 函数的执行。
|
||||
|
||||
- 参数2:如果 promise 的状态为 rejected(意思是,任务执行失败),则触发 onRejected 函数的执行。
|
||||
- 参数2:**失败的回调函数**。如果 Promise 的状态为 rejected(意思是,任务执行失败),则触发 onRejected 函数的执行。
|
||||
|
||||
3、**只有 Promise 的状态被改变之后,才会走到 then() 或者 catch()**。也就是说,在 new Promise() 时,如果没有写 resolve(),则 promise.then() 不执行;如果没有写 reject(),则 promise.catch() 不执行。
|
||||
|
||||
|
|
|
|||
|
|
@ -124,9 +124,9 @@ res3 qianguyihao
|
|||
|
||||
## then() 方法的返回值【重要】
|
||||
|
||||
> 这一段的知识点略有难度,但也很重要。
|
||||
> 这一段的知识点略有难度,但是非常重要,是我们学习 Promise 链式调用的理论基础。
|
||||
|
||||
then()方法本身是有返回值的,它会返回一个新的Promise对象。因为 then()方法的返回值永远是一个 Promise 对象,所以我们才可以对它进行链式调用。
|
||||
then()方法本身是有返回值的,它会返回一个新的Promise对象。因为 then()方法的返回值永远是一个 Promise 对象,所以我们才可以对它进行**链式调用**。
|
||||
|
||||
Promise 链式调用的伪代码:
|
||||
|
||||
|
|
@ -141,20 +141,22 @@ myPromise.then().then().catch()
|
|||
|
||||
1、当then方法中的回调函数在执行时,那么Promise 处于pending状态。
|
||||
|
||||
2、当 then方法中的回调函数中,手动 return 一个返回值时,那么 Promise 的状态取决于返回值的类型。当返回值这行代码执行完毕后, Promise 会立即决议,进入确定的状态。具体情况如下:
|
||||
2、当 then方法中的回调函数中,手动 return 一个返回值时,那么 Promise 的状态取决于返回值的类型。当返回值这行代码执行完毕后, Promise 会立即决议,进入确定状态。具体情况如下:
|
||||
|
||||
- 情况1:如果返回值是**普通的值或者普通对象**(包括return undefined的情况),那么 Promise 的状态为fulfilled。这个值会作为then()回调的参数。
|
||||
- 情况1:如果没有返回值(相当于 return undefined),或者返回值是**普通值/普通对象**,那么 Promise 的状态为fulfilled。这个值会作为then()回调的参数。
|
||||
- 情况2:如果返回值是**另外一个新的 Promise**,那么原 Promise 的状态将**交给新的 Promise 决定**。
|
||||
- 情况3:如果返回值是一个对象,并且这个对象里有实现then()方法(这种对象称为 **thenable** 对象),那就会执行该then()方法,并且根据**then()方法的结果来决定Promise的状态**。
|
||||
|
||||
还有一种特殊情况:
|
||||
|
||||
- 情况4:当then()方法传入的回调函数遇到异常或者抛出异常时,那么, Promise 处于rejected 状态。(后续再讲)
|
||||
|
||||
- 情况4:当then()方法传入的回调函数遇到异常或者抛出异常时,那么, Promise 处于rejected 状态。
|
||||
|
||||
**小结**:then()方法里,我们可以通过 return **传递结果**给下一个新的Promise。
|
||||
|
||||
### 默认返回值
|
||||
|
||||
如果then()方法里没写返回值(相当于 return undefined),那么它的返回值是一个新的Promise。新 Promise 的状态为fulfilled,其then()方法里,res的值为 undefined。
|
||||
|
||||
then() 链式调用的代码举例:
|
||||
|
||||
```js
|
||||
|
|
@ -204,10 +206,10 @@ res3:undefined
|
|||
|
||||
换句话说,第一个 then() 在等待 myPromise 的决议结果,有决议结果后执行;第二个 then() 在等待第一个 then()参数里返回的新 Promise的决议结果,有决议结果后执行;第三个 then() 在等待第二个 then()参数里返回的新 Promise的决议结果,有决议结果后执行。
|
||||
|
||||
此外,我们也可以在 then()的回调函数里,手动 return 自己想要的数据类型,可以有以下几种情况。
|
||||
|
||||
### 返回普通值
|
||||
|
||||
我们也可以在 then()方法里,手动 return 自己想要的数据,比如一个普通值 value1。这个普通值就可以传递给下一个新的Promise。新 Promise 的状态为fulfilled,其then()方法里,res的值为 value1。
|
||||
|
||||
代码举例:
|
||||
|
||||
```js
|
||||
|
|
@ -218,6 +220,7 @@ const myPromise = new Promise((resolve, reject) => {
|
|||
myPromise
|
||||
.then(res => {
|
||||
console.log('res1:', res);
|
||||
// return一个普通值,把这个值传递给下一个Promise
|
||||
return '2号';
|
||||
/*
|
||||
上面这行 return,相当于:
|
||||
|
|
@ -227,6 +230,7 @@ myPromise
|
|||
*/
|
||||
})
|
||||
.then(res => {
|
||||
// res可以接收到上一个 Promise 传递的值
|
||||
console.log('res2:', res);
|
||||
})
|
||||
.then(res => {
|
||||
|
|
@ -244,7 +248,7 @@ res3: undefined
|
|||
|
||||
### 返回新的 Promise
|
||||
|
||||
代码举例:
|
||||
1、在 then() 方法中return一个成功的Promise,代码举例:
|
||||
|
||||
```js
|
||||
const myPromise = new Promise((resolve, reject) => {
|
||||
|
|
@ -261,7 +265,7 @@ myPromise
|
|||
return myPromise2;
|
||||
})
|
||||
.then(res => {
|
||||
// 监听 myPromise2 的决议:
|
||||
// 监听 myPromise2 的成功状态
|
||||
console.log('res2:', res);
|
||||
})
|
||||
.then(res => {
|
||||
|
|
@ -277,6 +281,48 @@ res2: qianguyihao fulfilled 2
|
|||
res3 undefined
|
||||
```
|
||||
|
||||
2、通过then()的第二个参数走了失败的回调函数后,再走then() 会怎么样?代码举例:
|
||||
|
||||
```js
|
||||
const myPromise = new Promise((resolve, reject) => {
|
||||
resolve('qianguyihao fulfilled 1');
|
||||
});
|
||||
|
||||
const myPromise2 = new Promise((resolve, reject) => {
|
||||
reject('qianguyihao rejected 2');
|
||||
});
|
||||
|
||||
myPromise
|
||||
.then(res => {
|
||||
console.log('res1:', res);
|
||||
return myPromise2;
|
||||
})
|
||||
.then(res => {
|
||||
console.log('res2:', res);
|
||||
}, err => {
|
||||
// 如果 myPromise2 为失败状态,可以通过 then() 的第二个参数(即失败的回调函数)捕获异常,然后就可以继续往下执行其他 Promise
|
||||
console.log('err2:', err);
|
||||
// 这里相当于 return undefined
|
||||
})
|
||||
.then(res => {
|
||||
console.log('res3', res);
|
||||
}, err => {
|
||||
console.log('err3:', err);
|
||||
});
|
||||
```
|
||||
|
||||
打印结果:
|
||||
|
||||
```
|
||||
res1: qianguyihao fulfilled 1
|
||||
err2: qianguyihao rejected 2
|
||||
res3: undefined
|
||||
```
|
||||
|
||||
上方代码可以看到,最后一个 Promise 走的是成功回调,而不是失败回调。这例子一定要记住。这说明了,在多个Promise的链式调用里,**如果中间的某个Promise 执行失败,还想让剩下的其他 Promise 顺利执行**的话,那就请在中间**那个失败的Promise里加一个失败的回调函数**,捕获异常后,便可继续往下执行其他的Promise。
|
||||
|
||||
|
||||
|
||||
### 返回 thenable 对象
|
||||
|
||||
代码举例:
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ requestData1(params_1).then(res1 => {
|
|||
|
||||
### Promise 的链式调用写法【重要】
|
||||
|
||||
针对多个不同接口的嵌套调用,采用 Promise 链式调用的写法如下:(将上方代码的最后10行,改进如下)
|
||||
针对多个不同接口的嵌套调用,采用 Promise 的**链式调用**写法如下:(将上方代码的最后10行,改进如下)
|
||||
|
||||
```js
|
||||
requestData1(params_1).then(res1 => {
|
||||
|
|
@ -175,11 +175,11 @@ requestData1(params_1).then(res1 => {
|
|||
|
||||
其实还有更高级、更有水平的写法,那就是用生成器、用 async ... await 来写Promise的链式调用,也就是改进上面的十几行代码。你把它掌握了,编程水平才能更上一层楼。我们稍后会讲。
|
||||
|
||||
## Promise 链式调用:封装 Node.js 的回调方法
|
||||
### Promise 链式调用举例:封装 Node.js 的回调方法
|
||||
|
||||
代码结构与上面的类似,这里仅做代码举例,不再赘述。
|
||||
|
||||
### 传统写法
|
||||
传统写法:
|
||||
|
||||
```js
|
||||
fs.readFile(A, 'utf-8', function (err, data) {
|
||||
|
|
@ -193,7 +193,7 @@ fs.readFile(A, 'utf-8', function (err, data) {
|
|||
|
||||
上方代码多层嵌套,存在回调地狱的问题。
|
||||
|
||||
### Promise 写法
|
||||
Promise 写法:
|
||||
|
||||
```js
|
||||
function read(url) {
|
||||
|
|
@ -278,8 +278,9 @@ getData();
|
|||
|
||||
|
||||
|
||||
## 链式调用,如何处理失败的情况
|
||||
|
||||
|
||||
## 链式调用,如何处理 reject 失败状态
|
||||
|
||||
### 例 1:不处理 reject
|
||||
|
||||
|
|
@ -384,54 +385,7 @@ getPromise('a.json')
|
|||
|
||||
- a 请求成功,b 请求失败:然后会走到 catch,不执行 c。
|
||||
|
||||
## return 的返回值
|
||||
|
||||
return 后面的返回值,有两种情况:
|
||||
|
||||
- 情况 1:返回 Promise 实例对象。返回的该实例对象会调用下一个 then。
|
||||
|
||||
- 情况 2:返回普通值。返回的普通值会直接传递给下一个 then,通过 then 参数中函数的参数接收该值。
|
||||
|
||||
我们针对上面这两种情况,详细解释一下。
|
||||
|
||||
### 情况 1:返回 Promise 实例对象
|
||||
|
||||
举例如下:
|
||||
|
||||
```js
|
||||
getPromise('a.json')
|
||||
.then((res) => {
|
||||
// a 请求成功。从 resolve 获取正常结果:接口请求成功后,打印a接口的返回结果
|
||||
console.log(res);
|
||||
// 这里的 return,返回的是 Promise 实例对象
|
||||
return new Promise((resolve, reject) => {
|
||||
resolve('qianguyihao');
|
||||
});
|
||||
})
|
||||
.then((res) => {
|
||||
console.log(res);
|
||||
});
|
||||
```
|
||||
|
||||
### 情况 2:返回 普通值
|
||||
|
||||
```js
|
||||
getPromise('a.json')
|
||||
.then((res) => {
|
||||
// a 请求成功。从 resolve 获取正常结果:接口请求成功后,打印a接口的返回结果
|
||||
console.log(res);
|
||||
// 返回普通值
|
||||
return 'qianguyihao';
|
||||
})
|
||||
/*
|
||||
既然上方代码并没有返回 promise,那么,这里的 then 是谁来调用呢?
|
||||
答案是:这里会产生一个新的 默认的 promise实例,来调用这里的then,确保可以继续进行链式操作。
|
||||
*/
|
||||
.then((res2) => {
|
||||
// 这里的 res2 接收的是 普通值 'qianguyihao'
|
||||
console.log(res2);
|
||||
});
|
||||
```
|
||||
|
||||
## 赞赏作者
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue