美文网首页
【ECMAScript6】 Promise

【ECMAScript6】 Promise

作者: zbcy0012 | 来源:发表于2019-03-14 23:17 被阅读0次

    Promise 是什么

    Promise 是 ES6 为 JavaScript 异步编程定义的全新 api 。为异步编程而生,实际上就是另类的回调函数。

    为什么要使用 Promise

    • 代码更整洁,可读性强,易于维护(避免了回调地狱)。
    • 链式操作,容易编写,易于开发。

    API速查

    • promiseObj.then( resolve, reject )
    • promiseObj.catch( reject ) =====>(等同于 promiseObj.then( null, reject ))
    • Promise.resolve() =====>创建一个已完成态的 promise 对象
    • Promise.reject() =====>创建一个已拒绝态的 promise 对象

    使用方法

    promise() 之后总是会返回一个新的 promise 对象,因此而支持链式操作。

    1.基本用法

    const _p = new Promise((resolve, reject) => {
        console.log(1);
        resolve(2);
    });
    
    _p.then(
        res => {
            console.log(res);
        },
        err => {
            console.log(err);
        }
    );
    *************
    1
    2
    

    resolve 为当异步处理“成功”时调用的方法;reject 为异步处理“失败”时调用的方法。

    2.链式操作

    const _p = new Promise((resolve, reject) => {
        console.log(1);
        resolve(2);
    });
    
    _p.then(
        res => {
            console.log(res);
            return 3;          //把想要继续操作的数据 return 出来
        },
        err => {
            console.log(err);
        }
    ).then(res => {
        console.log(res);
    });
    *******************
    1
    2
    3
    

    行为探究

    1.时效性

    const _p = new Promise((resolve, reject) => {
        console.log(1);  //  这一条语句模拟了声明内容
        resolve(2);
    });
    
    _p.then(res => {
        console.log(res);
        return 3;
    }).then(res => {
        console.log(res);
    });
    *************
    1    
    2   
    3   
    
    const _p = new Promise((resolve, reject) => {
        //这里属于声明内容
        setTimeout(() => {
            console.log(1);
            resolve(2);
        }, 1000);
    });
    
    _p.then(res => {
        console.log(res);
        return 3;
    }).then(res => {
        console.log(res);
    });
    ******************
    1    //1秒后打印
    2    //1秒后打印
    3    //1秒后打印
    
    const getp = () => {
        //这里的 promise 对象是函数返回结果,所以直到函数 getp 被调用之前,
        //该promise 的声明内容都不在主线程当中,所以不会被立即执行。
        return new Promise((resolve, reject) => {
            console.log(1);
            resolve(2);
        });
    };
    
    setTimeout(() => {
        const _p = getp();
        _p.then(res => {
            console.log(res);
            return 3;
        }).then(res => {
            console.log(res);
        });
    }, 2000);
    **************
    1    //2秒后打印
    2    //2秒后打印
    3    //2秒后打印
    
    let _p = new Promise((resolve, reject) => {
        console.log(1);
        resolve(2);
    });
    
    //完成处理程序
    _p = _p.then(res => {
        console.log(res);
        return 3;
    });
    
    //完成处理程序
    _p.then(res => {
        console.log(res);
        return 4;
    });
    
    console.log(11);
    *****************
    1    
    11
    2    //完成处理程序被添加至任务队列末尾
    3    //完成处理程序被添加至任务队列末尾
    

    【结论】
    1. promise 的声明环境如果在主线程当中,那么其声明内容会被立即调用一次;而在 resolvereject 中传入的参数知道有下一次 .then() 动作时才会被使用。
    2. promise 的完成处理程序(resolve)和拒绝处理程序(reject)总是在执行器完成后被添加到任务队列的末尾。

    2.报错机制

    const _p = new Promise((resolve, reject) => {
        throw new Error(233);
    });
    
    _p.then(
        res => {
            console.log(res);
            return 3;
        }
        //此处不注册拒绝处理程序
    );
    ***************
    弹出错误
    
    const _p = new Promise((resolve, reject) => {
        throw new Error(233);
    });
    
    _p.then(
        res => {
            console.log(res);
            return 3;
        },
        //注册拒绝处理程序
        err => {
            console.log(err);
        }
    );
    ***************
    不弹出错误,打印错误信息
    
    const _p = new Promise((resolve, reject) => {
        throw new Error(233);
    });
    
    _p.then(
        res => {
            console.log(res);
            return 3;
        },
        //注册拒绝处理程序(但没有任何动作)
        err => {
            //console.log(err);
        }
    );
    ***************
    完全不报错
    
    const _p = new Promise((resolve, reject) => {
        console.log(2);
        resolve(2);
        console.log(3);
        throw new Error(233);
        console.log(4);
    });
    
    _p.then(
        res => {
            console.log(res);
            return 3;
        },
        //无论是否注册拒绝处理程序
        err => {
            console.log(err);
        }
    );
    *********
    2
    3
    2
    完全不报错
    
    const _p = new Promise((resolve, reject) => {
        console.log(2);
        throw new Error(233);
        console.log(3);
        resolve(2);
        console.log(4);
    });
    
    _p.then(
        res => {
            console.log(res);
            return 3;
        },
        err => {
            console.log(err);
        }
    );
    **********
    2
    打印错误信息
    

    【结论】
    1. 在 promise 进程中如果先遇到了 resolve 则后续即便遇上 error 也不会调用 reject;反之如果先遇到 error 则直接调用 reject,且永远不调用完成处理程序。

    上面的例子我们发现 resolve 之后的语句依然会被执行,直到遇见 error 或结束;反之 Error 之后的语句则无论如何都不会被执行了。

    2. 永远不要声明一个什么都不做的拒绝处理函数,因为你可能会在出现bug时得不到任何有效信息。

    ------------- 作者水平有限,如有错误,欢迎探讨指正 -------------

    相关文章

      网友评论

          本文标题:【ECMAScript6】 Promise

          本文链接:https://www.haomeiwen.com/subject/bczppqtx.html