Twelve, Promise study notes (basic use of Promise, chain programming, all())

1. Know Promise

A very important and useful feature in ES6 is Promise

  • But the first time you come into contact with Promise, you will be confused. What is this TM?
  • Looking at the introduction and usage of it in the official or some articles, it is also at a loss.

What exactly does Promise do?

  • Promise is a solution for asynchronous programming.

So when will we deal with asynchronous events?

  • A very common scenario should be network requests.
  • We encapsulate a network request function, because the result cannot be obtained immediately, so the result cannot be returned like a simple 3+4=7.
  • So often we will pass in another function, and when the data request is successful, the data will be called back out through the passed function.
  • If it is just a simple network request, then this solution will not cause us much trouble.

However, when the network request is very complex, callback hell will appear.
OK, I will illustrate with a very exaggerated case.
Let's consider the following scenario (with exaggeration):

  • We need to load a data data1 from the server through a url1, data1 contains the url2 of the next request
  • We need to retrieve url2 through data1, load data data2 from the server, and data2 contains the url3 of the next request
  • We need to retrieve url3 through data2, load data data3 from the server, data3 contains url4 of the next request
  • Send network request url4 to get the final data data4

Insert picture description here
Is there anything wrong with the above code?

  • Under normal circumstances, there will be no problems, it can run normally and get the results we want.
  • However, this code is ugly and not easy to maintain.

What we expect more is a more elegant way to carry out this kind of asynchronous operation.
How to do it?

  • It is to use Promise.
  • Promises can solve this problem in a very elegant way.

Two, the basic use of Promise

2.1 Asynchronous events of timers

Let's first take a look at the most basic syntax of Promise.

Here, we use a timer to simulate asynchronous events:

  • Assume that the following data is the data requested after 1 second from the network
  • console.log is our approach.
    Insert picture description here

The picture above is how we handled it in the past, we replaced it with Promise code:
Insert picture description here
this example will make us feel like we are taking off our pants and farting.

  • First of all, the Promise code below is obviously more complicated than the code above looks.
  • Secondly, what are the resolve, reject, then, and catch contained in the Promise code below?

Let's ignore the first complexity problem, because such a big program can't see the real role of Promise at all.

2.2 Timer asynchronous event analysis

Let's first take a serious look and really read what this program does?

  • new Promise is obviously to create a Promise object
  • The parentheses ((resolve, reject) => {}) is also obviously a function, and here we use the arrow function that we just learned before.

But what are resolve and reject?

  • We first know the fact: when creating a Promise, the arrow function passed in is fixed (usually we will write this way)
  • Both resolve and reject are also functions. Normally, we will decide which one to call based on the success or failure of the requested data.

Success or failure?

  • If it is successful, then we usually call resolve(messsage). At this time, our subsequent then will be called back.
  • If it fails, we usually call reject(error). At this time, our subsequent catch will be called back.

OK, this is the most basic use of Promise.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<script>
    // 1.使用setTimeout
    // setTimeout(() => {
    
    
    //     console.log('Hello world!');
    // }, 1000)


    // new Promise(参数) 参数->函数(resolve,reject)
    // resolve,reject它们本身又是函数
    // 链式编程
    /*new Promise((resolve,reject) => {
        // 第一次发生网络请求的代码
        setTimeout(() => {
            // console.log('Hello world!');
            resolve()
        }, 1000)
    }).then(() => {
        // 第一次拿到结果后的处理代码
        console.log('Hello world!');
        console.log('Hello world!');

        return new Promise((resolve, reject) => {
            // 第二次发生网络请求的代码
            setTimeout(() => {
                resolve()
            }, 1000)
        }).then(() => {
            // 第二次拿到结果后的处理代码
            console.log('Hello vuejs!');
            console.log('Hello vuejs!');

            return new Promise((resolve, reject) => {
                // 第三次发生网络请求的代码
                setTimeout(() => {
                    resolve()
                }, 1000)
            }).then(() => {
                // 第三次拿到结果后的处理代码
                console.log('Hello promise!');
                console.log('Hello promise!');
            })
        })
    })*/

    // 什么情况下会用到Promise?
    // 一般情况下是有异步操作时,会使用Promise对这个异步操作进行封装
    new Promise((resolve, reject) => {
    
    
        setTimeout(() => {
    
    
            // 成功的时候调用resolve
            // resolve('hello data')

            // 失败的时候调用reject
            reject('error message')
        }, 1000)
    }).then((data) => {
    
    
        console.log(data);
        console.log(data);
        console.log(data);
        console.log(data);
    }).catch((err) => {
    
    
        console.log(err);
    })

</script>
</body>
</html>
  1. Then() processing is successful, catch() processing fails:
    Insert picture description here

  2. Don't write catch(), pass the two functions that deal with success and failure as the parameters of the then() function:
    Insert picture description here

Three, the three states of Promise

First of all, when we have asynchronous operations in our development, we can wrap a Promise for the asynchronous operations

After asynchronous operation, there will be three states. Let's take a look at these three states together:
Insert picture description here

  1. pending: waiting state, such as a network request in progress, or the timer has not expired.
  2. fulfill: fulfilled state, when we actively call back resolve, we are in this state, and we will call back.then()
  3. Reject: Reject state, when we actively call back reject, we are in this state, and we will call back. catch()

Insert picture description here

Four, Promise chain programming

Insert picture description here

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    // 1.使用setTimeout
    // setTimeout(() => {
    
    
    //     console.log('Hello world!');
    // }, 1000)


    // new Promise(参数) 参数->函数(resolve,reject)
    // resolve,reject它们本身又是函数
    // 链式编程
    new Promise((resolve,reject) => {
    
    
        // 第一次发生网络请求的代码
        setTimeout(() => {
    
    
            // console.log('Hello world!');
            resolve()
        }, 1000)
    }).then(() => {
    
    
        // 第一次拿到结果后的处理代码
        console.log('Hello world!');
        console.log('Hello world!');

        return new Promise((resolve, reject) => {
    
    
            // 第二次发生网络请求的代码
            setTimeout(() => {
    
    
                resolve()
            }, 1000)
        }).then(() => {
    
    
            // 第二次拿到结果后的处理代码
            console.log('Hello vuejs!');
            console.log('Hello vuejs!');

            return new Promise((resolve, reject) => {
    
    
                // 第三次发生网络请求的代码
                setTimeout(() => {
    
    
                    resolve()
                }, 1000)
            }).then(() => {
    
    
                // 第三次拿到结果后的处理代码
                console.log('Hello promise!');
                console.log('Hello promise!');
            })
        })
    })
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<script>
    // 网络请求: aaa -> 处理代码(10行代码)
    // 处理:aaa111 -> 处理代码(10行代码)
    // 处理:aaa111222 -> 处理代码(10行代码)

    // new Promise((resolve, reject) => {})
    /* new Promise((resolve, reject) => {
         setTimeout(() => {
             resolve('aaa')
         }, 1000)
     }).then(res => {
         // 1.自己处理10行代码
         console.log(res, '第一层的10行处理代码')

         // 2.对结果进行第一次处理
         return new Promise((resolve, reject) => {
             resolve(res + '111')
         })

     }).then(res => {
         console.log(res, '第二层的10处理代码');

         return new Promise((resolve, reject) => {
             resolve(res + '222')
         })

     }).then(res => {
         console.log(res, '第三层的10处理代码');
     })
 */

    // 2.
    // new Promise((resolve, reject) => {
    
    
    //     setTimeout(() => {
    
    
    //         resolve('aaa')
    //     }, 1000)
    // }).then(res => {
    
    
    //     // 1.自己处理10行代码
    //     console.log(res,'第一层的10行处理代码')
    //
    //     // 2.对结果进行第一次处理
    //     // return new Promise((resolve, reject) => {
    
    
    //     //         resolve(res + '111')
    //     //     })
    //     return Promise.resolve(res + '111')
    //     }).then(res => {
    
    
    //         console.log(res, '第二层的10处理代码');
    //
    //         return Promise.resolve(res + '222')
    //
    //         }).then(res => {
    
    
    //             console.log(res, '第三层的10处理代码');
    //         })

    // 链式调用中间某一层出现reject的情况,会直接执行最后面的catch()
    // new Promise((resolve, reject) => {
    
    
    //     setTimeout(() => {
    
    
    //         resolve('aaa')
    //     }, 1000)
    // }).then(res => {
    
    
    //     // 1.自己处理10行代码
    //     console.log(res, '第一层的10行处理代码')
    //
    //     // 2.对结果进行第一次处理
    //     // return new Promise((resolve, reject) => {
    
    
    //     //         resolve(res + '111')
    //     //     })
    //     return Promise.reject('error message')
    // }).then(res => {
    
    
    //     console.log(res, '第二层的10处理代码');
    //
    //     return Promise.resolve(res + '222')
    //
    // }).then(res => {
    
    
    //     console.log(res, '第三层的10处理代码');
    // }).catch(err => {
    
    
    //     console.log(err);
    // })

   // throw
    new Promise((resolve, reject) => {
    
    
        setTimeout(() => {
    
    
            resolve('aaa')
        }, 1000)
    }).then(res => {
    
    
        // 1.自己处理10行代码
        console.log(res, '第一层的10行处理代码')

        // 2.对结果进行第一次处理
        // return new Promise((resolve, reject) => {
    
    
        //         resolve(res + '111')
        //     })
        throw 'error message'
    }).then(res => {
    
    
        console.log(res, '第二层的10处理代码');

        return Promise.resolve(res + '222')

    }).then(res => {
    
    
        console.log(res, '第三层的10处理代码');
    }).catch(err => {
    
    
        console.log(err);
    })


    // 3.省略掉Promise.resolve
    // new Promise((resolve, reject) => {
    
    
    //     setTimeout(() => {
    
    
    //         resolve('aaa')
    //     }, 1000)
    // }).then(res => {
    
    
    //     // 1.自己处理10行代码
    //     console.log(res, '第一层的10行处理代码')
    //
    //     return res + '111'
    // }).then(res => {
    
    
    //     console.log(res, '第二层的10处理代码');
    //
    //     return res + '222'
    //
    // }).then(res => {
    
    
    //     console.log(res, '第三层的10处理代码');
    // })


</script>
</body>
</html>

4.1 chain call

  • When we looked at the flowchart of Promise, we found that both then and catch can return a Promise object.

  • Therefore, our code can actually be chained:
    Insert picture description here

  • Here we directly wrap the new data through Promise and return the Promise object

  1. Promise.resovle(): wrap the data into a Promise object and call back the resolve() function internally
  2. Promise.reject(): wrap the data into a Promise object and call back the reject() function internally

4.2 Shorthand for chain call


Simplified code: If we want the data to be directly packaged into Promise.resolve, then the data can be returned directly in then

  • Note that in the code below, I will return Promise.resovle(data)change it return data, and the result is still the same

Insert picture description here

4.3 Use of all method

When you need multiple network requests to succeed before proceeding to the next step, you can use the all method of Promise:
Insert picture description here

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<script>
    // Promise.all([
        // new Promise((resolve, reject) => {
    
    
        //     $ajax({
    
    
        //         url: 'url1',
        //         success: function (data) {
    
    
        //             resolve(data)
        //         }
        //     })
        // }),
        //
        // new Promise((resolve, reject) => {
    
    
        //     $ajax({
    
    
        //         url: 'url2',
        //         success: function (data) {
    
    
        //             resolve(data)
        //         }
        //     })
        // })
    Promise.all([
        new Promise((resolve, reject) => {
    
    
            setTimeout(() => {
    
    
                resolve('result1')
            },2000)
        }),

        new Promise((resolve, reject) => {
    
    
            setTimeout(() => {
    
    
                resolve('result2')
            },1000)
        })

    ]).then(results => {
    
    
        console.log(results);
    })

</script>
</body>
</html>

Guess you like

Origin blog.csdn.net/weixin_44827418/article/details/113517342