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)
    });
  • 相关阅读:
    ASP.NET编程的十大技巧
    C#学习心得(转)
    POJ 1177 Picture (线段树)
    POJ 3067 Japan (树状数组)
    POJ 2828 Buy Tickets (线段树)
    POJ 1195 Mobile phones (二维树状数组)
    HDU 4235 Flowers (线段树)
    POJ 2886 Who Gets the Most Candies? (线段树)
    POJ 2418 Cows (树状数组)
    HDU 4339 Query (线段树)
  • 原文地址:https://www.cnblogs.com/waitforyou/p/6930767.html
Copyright © 2011-2022 走看看