update: Promise中,then() 方法的返回值

This commit is contained in:
qianguyihao 2023-06-12 00:12:25 +08:00
parent c4621ae2f7
commit 2dbce6df1c
3 changed files with 64 additions and 64 deletions

View File

@ -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() 不执行。

View File

@ -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 @@ res3undefined
换句话说,第一个 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 对象
代码举例:

View File

@ -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);
});
```
## 赞赏作者