zoukankan      html  css  js  c++  java
  • Promise学习

    ES6中一个非常重要和好用的特性就是Promise,它是异步编程的一种解决方案。一种很常见的场景应该就是网络请求了。

    1、简单案例

    Promise 本身接受一个函数 function(resolve, reject)作为参数,而接受的这个匿名函数的两个参数 resolvereject 本身也是一个函数

    new Promise((resolve, reject) => {
        console.log('request1')
        setTimeout(() => {
            resolve()
        }, 1000)            
    }).then(() => {
        console.log('handle1')
        return new Promise((resolve, reject) => {
            console.log('request2');
            resolve()
        })
    }).then(() => {
        console.log('handle2')
    }).catch(data => {
        console.log(data)
    })
    

    2、catch的另一种写法

    正常情况下我们应该这么写捕获 reject

    new Promise((resolve, reject) => {
        console.log('request1')
        setTimeout(() => {
            reject('error message')
        }, 1000)            
    }).then(data => {
    
    }).catch(err => {
        console.log(err);
    })
    

    而另一种就是下面的方法

    new Promise((resolve, reject) => {
        console.log('request1')
        setTimeout(() => {
            reject('error message')
        }, 1000)            
    }).then(data => {
    
    }, err => {
        console.log(err);
    })
    

    输出结果

    request1
    error message
    

    3、简写

    3.1 什么时候可以简写

    现在回头看开头的简单案例,发现只有第一个 Promise 是异步请求,而剩下的几个都是获取前一步的操作结果,面对这种情况就可以简写了,如下

    new Promise((resolve, reject) => {
        console.log('request1')
        setTimeout(() => {
            resolve('data')
        }, 50)
    }).then(data => {
        console.log('handle1: data =', data);
        return Promise.resolve(data + '111')
    }).then(data => {
        console.log('handle2: data =', data);
        return Promise.reject('err msg')
    }).then(data => {
        console.log('handle3: data =', data);
        return Promise.resolve(data + '333')
    }).catch(res => {
        console.log(res)
    })
    

    输出结果

    request1
    handle1: data = data
    handle2: data = data111
    err msg
    

    当不进行异步操作,而直接传递数据时可以直接用 Promise.resolve()Promise.reject()传递数据,就不用再麻烦的封装 new Promise((resolve.reject))

    3.2 更进一步简写

    对于Promise.resolve()还有更进一步的简写,如下

    new Promise((resolve, reject) => {
        console.log('request1')
        setTimeout(() => {
            resolve('data')
        }, 50)            
    }).then(data => {
        console.log('handle1: data =', data);
        return data + '111'
    }).then(data => {
        console.log('handle2: data =', data);
        return data + '222'
    }).then(data => {
        console.log('handle3: data =', data);
        throw 'err msg'
    }).catch(err => {
        console.log(err);
    })
    

    输出结果

    request1
    handle1: data = data
    handle2: data = data111
    handle3: data = data111222
    err msg
    

    直接返回即可,无需用 Promise.resolve()封装。而对于 Promise.reject() ,可以用 throw将错误信息抛出

    4、Promise.all(iterator)

    现在有这样的一个需求,就是当 url1 请求和 url2 请求全部完成后,才能进行操作

    4.1 普通写法

    var res1 = false
    var res2 = false
    
    $.ajax({
        url: 'url1',
        success: function(res){
    		res1 = true
            handleResult(res)
        }
    })
    $.ajax({
        url: 'url2',
        success: function(res){
    		res2 = true
            handleResult(res)
        }
    })
    
    function handleResult(res){
        if(res1 && res2){
            ....
        }
    }
    

    这样虽然可行,但是还需定义2个变量,1个函数,十分的别扭

    4.2 Promise.all() 写法

    Promise.all([
        new Promise((resolve, reject) => {
            $.ajax({
                url: 'url1',
                success: function(res){
                    resolve(res) // 设res为 {name: 'bob', age: 18}
                }
            })
        }), 
        new Promise((resolve, reject) => {
            $.ajax({
                url: 'url2',
                success: function(res){
                    resovle(res)// 设res为 {name: 'tim', age: 22}
                }
            })
        })
    ]).then(result => {
        console.log(result)
    })
    

    那么可以得到下面的结果

     [{name: 'bob', age: 18}, {name: 'tim', age: 22}]
    
    作者: 贺墨于
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    程序员书单
    36条极简人生建议
    Nacos
    jvm详解
    22种世界500强都在用的高效工作方法,你了解几种?
    道德经39经典
    积累的力量
    JUC之线程间定制化通信
    JVM调优参考
    docker开机启动和dockercompose开机启动执行相应的各个docker容器
  • 原文地址:https://www.cnblogs.com/hemou/p/14380522.html
Copyright © 2011-2022 走看看