Promise是什么鬼?

2018-08-09  本文已影响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都可以

    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后数组形式返回两个异步函数的结果

    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也不错

上一篇 下一篇

猜你喜欢

热点阅读