zoukankan      html  css  js  c++  java
  • JavaScript ES6 promiss的理解。

      本着互联网的分享精神,我将我对promise的理解分享给大家。 

      JavaScript ES6的promise方法主要应用在处理异步函数返回的结果,注意他不是将异步函数转换为同步函数,而是等异步函数有结果时在调用相应的方法进行处理。

    promise有以下方法

      then() - 它最多需要有两个参数,第一个是成功后调用的方法,第二个是失败后调用的方法。

      catch() - 失败后调用的方法,他与then方法的失败后调用的方法类似,但是使用上有些区别,等下我会用案例讲解。

      all() - 接收一个数组作为参数,数组内可填写异步函数,当所有的异步函数都执行完后,会返回一个promise执行后的数组。但是有一点需要注意的是,入过参数内有一个方法报错那么他就会报错,并不会返回结果。

      race() - 他与all的方法类似也接受一个数组作为参数(也是如如果数组内有一个方法报错那么他将会报错,不会返回结果),但是有一点不同的是只返回一个结果,那就是哪个哪个函数最先执行完成返回的哪个结果。

      resolve() - 和then的第一个参数一样,返回一个promise成功后调用方法。

      reject() - 和then的第二个参数一样,返回一个promise失败后调用的方法。

    万恶的异步套回调。

      本案例中我使用定时器模拟ajax服务器异步请求。

    function Fun(a, b, cb) {
        setTimeout(function () {
            cb(a + b)
        }, 1000)
    }
    
    Fun(1, 2 ,function (result) {
        console.log(result)
    });
    console.log(5); // 此时会先输出5在输出3

      在复杂一点的案例肯定是回调套回调,这样做肯定是没有错代码也会执行,但是逻辑上不是很清晰。

    function Fun(a, b, cb) {
        setTimeout(function () {
            cb(a + b)
        }, 1000)
    }
    
    Fun(1, 2, function (result) {
        if (result > 1) {
            Fun(result, 2, function (result) {
                Fun(result, 3, function (result) {
                    console.log('完成', result)
                })
            })
        }
    });
    console.log(5); // 此时会先输出5在输出  完成 8

     使用promise方法重写上面的案例- then的使用

    function Fun(a, b) {
        return new Promise(function (resolve, reject) {
            setTimeout(function () {
                resolve(a + b)
            }, 1000)
        })
    }
    Fun(1, 2)
        .then(function (result) {
            if (result > 1) {
                return Fun(result, 2)
            }
        })
        .then(function (result) {
            if (result > 1) {
                return Fun(result, 3)
            }
        }).then(function (result) {
        console.log('完成', result)
    });

    使用then方法处理错误失败

      then的第一个参数是处理Promise成功后使用的方法,第二个参数是Promise处理失败后的方法,下面的案例我将会模拟错误。

      如果Fun函数内传入的参数不是number类型,则触发then方法的错误处理函数,也就是第二个函数,当然第一个函数就不会执行了。

    function Fun(a, b) {
        return new Promise(function (resolve, reject) {
            if (typeof a !== 'number' || typeof b !== 'number') {
                reject(new Error('no number'))
            }
            setTimeout(function () {
                resolve(a + b)
            }, 1000)
        })
    }
    Fun(1, '1')
        .then(function (result) {
            if (result > 1) {
                return Fun(result, 2)
            }
        }, function (err) {    //这个方法将会被执行,因为报错了么,很好理解吧
            console.log(err )
        })
        .then(function (result) {
            console.log('第二个then'); //输出 第二个then 如果第一个then中的错误方法运用的妥当,对这里是不会有影响的,但是我并没有做相应的处理 只是输出了err, result返回的是undefined,if中的方法也就不会执行了。
            if (result > 1) {
                return Fun(result, 3)
            }
        });

     使用 catch捕获错误 - catch方法的使用

      then方法是从上向下运行,运行的中如果有发生错误的那么then方法就会在发生错误哪里停止运行,并且调用错误方法。注意:他与then的方法不同,then的处理机制处理完会继续向下执行,而catch却不会,会跳过未执行的then直接进入catch

    function Fun(a, b) {
        return new Promise(function (resolve, reject) {
            if (typeof a !== 'number' || typeof b !== 'number') {
                reject(new Error('no number'))
            }
            setTimeout(function () {
                resolve(a + b)
            }, 1000)
        })
    }
    Fun(1, 1)
        .then(function (result) {
            if (result > 1) {
                console.log(1)  // 1正常输出。
                return Fun(result, '2') //这里2不是number类型.
            }
        })
        .then(function (result) { // 由于上面传入的参数不是number类型,这里的then 就会调用错误处理,也就是说会执行catch方法。
         console.log(2) // 不会执行
    if (result > 1) { return Fun(result, 3) } }) .then(function (result) {
         console.log(3) // 不会执行 console.log(
    '完成', result) }) .catch( function (err) {//会被执行 no number console.log(err) } );

      还有一种情况主动抛出异常被catch捕获

    function Fun(a, b) {
        return new Promise(function (resolve, reject) {
            if (typeof a !== 'number' || typeof b !== 'number') {
                reject(new Error('no number'))
            }
            setTimeout(function () {
                resolve(a + b)
            }, 1000)
        })
    }
    Fun(1, 1)
        .then(function (result) {
                if (result > 1) {
                    if (result === 2) {
                        throw new Error('我要抛出错误因为我任性' + result) //主动抛出异常
                    }
                    console.log(1) 
                    return Fun(result, 2) 
                }
            }
        )
        .then(function (result) { 
            console.log(2) 
            if (result > 1) {
                return Fun(result, 3)
            }
        })
        .then(function (result) {
            console.log(3)
            console.log('完成', result)
        })
        .catch(function (err) { // 我要抛出错误因为我任性2
            console.log(err)
        });

    如果使用catch和then的第二个参数同时捕获参数会怎么样呢?

      如果then方法有第二个参数那么catch就不会执行,就会执行自己的第二个参数。可以将catch理解为接盘侠,如果then没有处理错误的方法,那么catch内的方法就会执行,如果同时没有then的第二个方法和catch那么就不会报错,因为压根就没有错误的处理机制那么就不会报错了。

    function Fun(a, b) {
        return new Promise(function (resolve, reject) {
            if (typeof a !== 'number' || typeof b !== 'number') {
                reject(new Error('no number'))
            }
            setTimeout(function () {
                resolve(a + b)
            }, 1000)
        })
    }
    Fun(1, '1')
        .then(function (result) {
            if (result > 1) {
                return Fun(result, 2)
            }
        }, function (err) {   //执行 输出 no number +12
            console.log(err + '12')   
        })
        .then(function (result) {
            console.log('第二个then'); // 执行输出 第二个then  
            if (result > 1) {  //这里不会执行因为没有result 因为result 是undefined 如果在第一个then的处理方法内处理的妥当这里就可以执行。
                return Fun(result, 3)
            }
        })
        .catch(function (err) {  //这里不会执行,因为每个then有自己的处理方式,所以catch就不会执行。
            console.log(err + '我是catch的错误处理')
        });

     all和race方法的使用

      这种方法在我们日常的项目中很常见,但是这种代码使用起来过于繁琐,那么那有没有更好的方法呢?

    function Fun(a, b) {
        return new Promise(function (resolve, reject) {
            if (typeof a !== 'number' || typeof b !== 'number') {
                reject(new Error('no number'))
            }
            setTimeout(function () {
                resolve(a + b)
            }, 1000)
        })
    }
    let resultList = [];
    Fun(1, 2)
        .then(function (result) {
            resultList.push(result);
            return Fun(2, 3)
        })
        .then(function (result) {
            resultList.push(result)
            console.log(resultList)
        });

      使用all方法实现上面的案例,

      all方法接收一个数组作为参数,数组内是方法,all会按照先后顺序返回一个执行后的数组。

    function Fun(a, b) {
        return new Promise(function (resolve, reject) {
            if (typeof a !== 'number' || typeof b !== 'number') {
                reject(new Error('no number'))
            }
            setTimeout(function () {
                resolve(a + b)
            }, 1000)
        })
    }
    var promise = Promise.all([Fun(1, 2), Fun(2, 3)]);
    promise.then(function (resule) {
        console.log(resule)  //输出 3 5
    });

      race方法的使用

      race方法使用和all方法类似,但是返回结果不同,all方法返回全部结果,race返回的是最先被执行完成那个函数的结果。注意:race接收参数的数组内,如果有一个方法报错,那么就不会返回结果。

    function Fun(a, b ,time) {
        return new Promise(function (resolve, reject) {
            if (typeof a !== 'number' || typeof b !== 'number') {
                reject(new Error('no number'))
            }
            setTimeout(function () {
                resolve(a + b)
            }, time)
        })
    }
    var promise = Promise.race([Fun(1, 2,1000), Fun(2, 3,200)]);
    //race  那个结果先被得到那么就会返回第一个得到的结果、但是如果整体有一个是错误的,那么就会抛出异常而不会得到结果。
    promise.then(function (resule) {
        console.log(resule)  //输出5
    });

     reject和resolve的使用

    reject返回的事一个抛出异常错误的方法。所以then的第二个函数或者是catch会被执行。

    var promise = Promise.reject("我要抛出错误");
    
    promise.then(function (reason) {
        // 未被调用
        console.log('reason')
    }, function (reason) {
        console.log(reason);//执行,因为reject就是抛出异常的方法。
    });

    resolve返回的事一个正常执行的方法,所以then的第一个函数会被执行。

    var promise = Promise.resolve("我是会被执行的")
    promise.then(function (value) {
        console.log(value); // "我是会被执行的"
    }, function (value) {
        // 不会被调用
        console.log(value)
    });
  • 相关阅读:
    SpringCloud分布式开发五大神兽
    Spring Cloud 架构 五大神兽的功能
    kafka 基础知识梳理-kafka是一种高吞吐量的分布式发布订阅消息系统
    ETL工具之Kettle的简单使用一(不同数据库之间的数据抽取-转换-加载)
    libjson 编译和使用
    一个用C++写的Json解析与处理库
    DB-library 常用函数
    什么是C++虚函数、虚函数的作用和使用方法
    C++用iconv进行页面字符转换
    QT学习:c++解析html相关
  • 原文地址:https://www.cnblogs.com/waitforyou/p/6930767.html
Copyright © 2011-2022 走看看