• ES6 Promise的使用详解


    Promise是ES6的一个用于处理异步操作的库。他本身是没有异步功能的,只是更方便异步操作而已。如果你用过类似rxjava的库的话,你就很容易明白。不过比rxjava简单的多。没用过也没关系。

    在前端应用种,我们经常需要发送网络请求。有可能通过一个url请求到另一个url,在通过这个url请求到第三个url。可能嵌套个4 5层。例如下面的代码,这样的代码是非常难以维护的。Promise就可以专门用来处理这种问题。

    $ajax{
     //100行逻辑处理
     $ajax{
     	//100行逻辑处理
     	$ajax{
     		//100行逻辑处理
    		 $ajax{
    			 //100行逻辑处理
    			 $ajax{
    				 //100行逻辑处理
    			}
    		 }
    	 }
    	 }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    Promise入门例子

    我们先写一个嵌套的例子。然后用Promise进行改造。
    下面这个代码就是所谓的回调地狱。如果代码很多,那么将非常的混乱。

    setTimeout(()=>{
        console.log("Hello World")
        console.log("Hello World")
        console.log("Hello World")
        console.log("Hello World")
        console.log("Hello World")
        setTimeout(()=>{
            console.log("Hello JS")
            console.log("Hello JS")
            console.log("Hello JS")
            console.log("Hello JS")
            console.log("Hello JS")
            setTimeout(()=>{
                console.log("Hello Python")
                console.log("Hello Python")
                console.log("Hello Python")
                console.log("Hello Python")
                console.log("Hello Python")
            },1000)
        },1000)
    },1000)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    我们用Promise就可以写成下面的代码。
    这代码怎么还变多了?代码多少不是关键,关键是代码结构变得清晰了。而且变成了链式编程。也就是嵌套的问题没有了,现在所以的代码都处在同一级上,至少从结构上来说是这样。
    代码多不是问题,后面介绍简写的写法。简写之后只能用一个词形容,就是优雅。后面介绍。

    new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve()
        }, 1000)
    }).then(() => {
        console.log("Hello World")
        console.log("Hello World")
        console.log("Hello World")
        console.log("Hello World")
        console.log("Hello World")
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve()
            }, 1000)
        })
    }).then(() => {
        console.log("Hello JS")
        console.log("Hello JS")
        console.log("Hello JS")
        console.log("Hello JS")
        console.log("Hello JS")
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve()
            }, 1000)
        })
    }).then(() => {
        console.log("Hello Python")
        console.log("Hello Python")
        console.log("Hello Python")
        console.log("Hello Python")
        console.log("Hello Python")
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    请求失败的情况,如果请求失败,可以调用reject方法,并且在catch处理错误。后面的操作都会中断。

    new Promise((resolve, reject) => {
        setTimeout(() => {
           // resolve()
            reject("err message")
        }, 1000)
    }).then(() => {
        console.log("Hello World")
        console.log("Hello World")
        console.log("Hello World")
        console.log("Hello World")
        console.log("Hello World")
    }).catch((err)=>{
        console.log(err);
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    还有一种处理错误的方式是使用then的第二个参数,可以直接处理错误的情况。

    new Promise((resolve, reject) => {
        setTimeout(() => {
            // resolve()
            reject("err message")
        }, 1000)
    }).then(() => {
        console.log("Hello World")
        console.log("Hello World")
        console.log("Hello World")
        console.log("Hello World")
        console.log("Hello World")
    }, err => {
        console.log(err);
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    还可以使用Promise进行任务方便,分步操作。

    //使用Promise进行多次处理,任务分解。
    new Promise((resolve, reject) => {
        setTimeout(() => {
              resolve("aaa")
        }, 1000)
    }).then(res => {
        console.log("第一次10行处理")
        return new Promise(resolve => {
            //对结果进行第一次处理
            resolve(res+"111")
        })
    }).then(res=>{
        console.log("第二次10行处理")
        return new Promise(resolve => {
            //对结果进行第一次处理
            resolve(res+"222")
        })
    }).then(res=>{
        console.log("第三次10行处理")
        return new Promise(resolve => {
            //对结果进行第一次处理
            resolve(res+"333")
        })
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    上面的写法可以简写成下面的样子,代码少了很多。

    //使用Promise进行多次处理,任务分解。
    new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve("aaa")
        }, 1000)
    }).then(res => {
        console.log("第一次10行处理")
        return Promise.resolve(res + "111")
    }).then(res => {
        console.log("第二次10行处理")
        return Promise.resolve(res + "222")
    }).then(res => {
        console.log("第三次10行处理")
        return Promise.resolve(res + "333")
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    处理错误的简写形式。

    //还能进一步简写,Promise都不想写,这样已经非常舒服了
    new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve("aaa")
        }, 1000)
    }).then(res => {
        console.log("第一次10行处理")
        return res + "111"
    }).then(res => {
        console.log("第二次10行处理")
        return Promise.reject("err message")
    }).then(res => {
        console.log("第三次10行处理")
        return res + "333"
    }).catch(err=>{
        console.log("err message from second process")
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    监听多个请求的结束时机

    有这样的需求,在两个请求都返回结果后,发生第三个请求。关键点就是我们怎么监听到前面两个请求什么时候结束。
    Promise为我们提供了all方法来处理这个问题。
    也是非常的简洁好用。

    Promise.all([
        new Promise((resolve, reject) => {
            setTimeout(()=>{
                console.log("开始第一个请求")
                resolve("result1")
            },2000)
    
        }),
        new Promise((resolve, reject) => {
            setTimeout(()=>{
                console.log("开始第二个请求")
                resolve("result2")
            },1000)
        })
    ]).then(results=>{
        console.log(results[0])
        console.log(results[1])
        console.log("开始第三个请求")
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
  • 相关阅读:
    计算机组成原理
    vscode下无法识别node、npm的问题
    SpringBoot集成swagger
    根据先序遍历和中序遍历生成后序遍历
    软件测试的需求人才越来越多,为什么大家还是不太愿意走软件测试的道路?
    【大学总结】迟到但未缺席的大学总结
    Win7缺失dll文件如何修复?Win7计算机丢失dll文件怎么办
    摆个小吃摊真是累人
    2023年全球及中国层析系统市场发展趋势分析:未来层析设备市场将持续增长[图]
    多肽计算符计算:modlamp 包
  • 原文地址:https://blog.csdn.net/ScottePerk/article/details/126892622