美文网首页
Promise是什么鬼?

Promise是什么鬼?

作者: 前端开发工程师老唐 | 来源:发表于2018-08-09 16:41 被阅读0次

    用vue的时候ajax是用的axios封装,一直不知道为何有.then这样简洁明了的写法,
    方便的背后一直没有去深究其理,今天就来看看Promise


    总所周知js是单线程,导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行。异步执行可以用回调函数实现,如经典的ajax,是这么玩的:

    request.onreadystatechange = function () {
        if (request.readyState === 4) {
            if (request.status === 200) {
                return success(request.responseText);
            } else {
                return fail(request.status);
            }
        }
    }
    

    用了异步是这样的:

    ajax.then(callback(success)).catch(callback(error))
    

    so:看看怎么封装Promise:
    在我看来Promise就是个语法糖,按照特定的写法进行解析而已:
    引用下廖雪峰官网的一句总结:

    来自廖雪峰官网

    玩个简单的比较傻逼的 promise game,看看Promise是怎么玩的,直接上代码:

    <script>
        function add(count) {
            return new Promise(function (res,  rej) { 
                count++;
                console.log(`current count: ${count}`);
                if (count < 5) { //满足条件的时候都执行res
                    setTimeout(() => {
                        res(count);
                    }, 500);
                } else { 
                    rej("promise game over")
                }
            })
        }
    
        p = new Promise((resolve,  reject) => { //p为一个promise实例,没有做条件判断,只会执行resolve
            let count = 0;
            console.log('start game:' + count)
            resolve(count);
        })
    
        p.then(add)
            .then(add)
            .then(add)
            .then(add)
            .then(add)
            .then(add)
            .then(add)
            .then(add)
            .then(add)
            .catch((error) => {
                console.log('hahaha'+ error)
            })
    </script>
    

    结果:

    start game:0
    test.html:5 current count: 1
    test.html:5 current count: 2
    test.html:5 current count: 3
    test.html:5 current count: 4
    test.html:5 current count: 5
    test.html:5 current count: 6
    test.html:32 hahahapromise game over

    catch 中执行rejcet回调


    所以: Promise对象就是参数中的resolve和reject两个参数分别放到then和catch中执行。而且和
    两个参数的名字没关系,参数名字可以写成res,rej都可以

    • 除了串行执行若干异步任务外,Promise还可以并行执行异步任务。

        p1 = new Promise(function(resolve, reject){
            let time = 2000;
            setTimeout(() => {
                resolve("p1返回了" + time)
            }, time);
        })
    
        p2 = new Promise(function(resolve, reject){
            let time = 3000;
            setTimeout(() => {
                resolve("p2返回了" + time)
            }, time);
        })
        let startTime = Date.parse(new Date());
        Promise.all([p1, p2]).then((result)=>{
            console.log(result)
            let useTime = (Date.parse(new Date()) - startTime)/1000;
            console.log("use:" + useTime + 's')
        })
    

    会在两个promise都执行完后才一起返回结果,应用场景是在同时两个异步请求完成需要计算的时候,代码运行结果:

    ["p1返回了2000", "p2返回了3000"]
    use:3s

    3s后数组形式返回两个异步函数的结果

    • 有些时候,多个异步任务是为了容错。比如,同时向两个URL读取用户的个人信息,只需要获得先返回的结果即可。这种情况下,用Promise.race()实现:

        p1 = new Promise(function(resolve, reject){
            let time = 2000;
            setTimeout(() => {
                resolve("p1返回了" + time)
            }, time);
        })
    
        p2 = new Promise(function(resolve, reject){
            let time = 3000;
            setTimeout(() => {
                resolve("p2返回了" + time)
            }, time);
        })
        let startTime = Date.parse(new Date());
        Promise.race([p1, p2]).then((result)=>{
            console.log(result)
            let useTime = (Date.parse(new Date()) - startTime)/1000;
            console.log("use:" + useTime + 's')
        })
    

    会返回先执行的一个函数,忽略掉剩下的函数,代码运行结果:

    p1返回了2000
    use:2s

    2s后返回p1的结果,忽略了p2

    写在结尾的:玩够了回调地狱,玩玩promise也不错

    相关文章

      网友评论

          本文标题:Promise是什么鬼?

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