Promise实现小球的运动

promise异步编程
一.起源
JavaScript中的异步由来已久,不论是定时函数,事件处理函数还是ajax异步加载都是异步编程的一种形式,我们现在以nodejs中实现三个小球的运动为例:

这里嵌套了6个异步回调函数,他们的执行时刻都是不可预测的并且这样写代码也不符合普通程序的执行流程,所以,问题来了。promise提供了一个解决上述问题的模式。

animate(ball1,100,function () {
        animate(ball2,200,function () {
            animate(ball3,300,function () {
                animate(ball3,150,function () {
                    animate(ball2,150,function () {
                        animate(ball1,150,function () {
                        })
                    })
                })
            })
        })
    })

2.接口

promise唯一接口then方法,它需要2个参数,分别是resolveHandler和rejectedHandler。并且返回一个promise对象来支持链式调用。

promise的构造函数接受一个函数参数,参数形式是固定的异步任务。

三.实现

要实现promise对象,首先要考虑几个问题:

1.promise构造函数中要实现异步对象状态和回调函数的剥离,并且分离之后能够还能使回调函数正常执行

2.如何实现链式调用并且管理状态

首先是构造函数:

/*引入promise对象*/
   var Promise=window.Promise
    function promiseAnimate(ball,distance) {
        return new Promise(function (resolve, reject) {
            function _animate() {
                setTimeout(function () {
                    var marginLeft = parseInt(ball.style.marginLeft, 10)
                    if (marginLeft === distance) {
                        resolve()
                    } else {
                        if (marginLeft < distance) {
                            marginLeft++
                        } else {
                            marginLeft--
                        }
                        ball.style.marginLeft = marginLeft+'px'
                        _animate()
                    }
                }, 13)
            }

            _animate();
        })
    }

构造函数接受一个异步函数,并且执行这个异步函数,修改promise对象的状态和结果。

回调函数方法then:

/*用romise的方式实现小球的运动*/
    promiseAnimate(ball1,100)
        .then(function () {
            return promiseAnimate(ball2,200)
        })
        .then(function () {
            return promiseAnimate(ball3,300)
        })
        .then(function () {
            return promiseAnimate(ball3,150)
        })
        .then(function () {
            return promiseAnimate(ball2,150)
        })
        .then(function () {
            return promiseAnimate(ball1,150)
        })

四、Promise实现小球的运动的完整代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Promise animation</title>
    <style>
        .ball{
            width: 40px;
            height: 40px;
            border-radius: 20px;
        }
        .ball1{
            background: red;
        }

        .ball2{
            background: yellow;
        }

        .ball3{
            background: green;
        }
    </style>
    <script src="./node_modules/bluebird/js/browser/bluebird.js"></script>

</head>
<body>
<div class="ball ball1" style="margin-left: 0;"></div>
<div class="ball ball2" style="margin-left: 0;"></div>
<div class="ball ball3" style="margin-left: 0;"></div>

<script>
    var ball1=document.querySelector('.ball1')
    var ball2=document.querySelector('.ball2')
    var ball3=document.querySelector('.ball3')

    function  animate(ball,distance,cb) {
        setTimeout(function () {
            var marginLeft=parseInt(ball.style.marginLeft,10)
            if(marginLeft===distance){
                cb && cb()
            }else{
                if(marginLeft<distance){
                   marginLeft++
                }else {
                    marginLeft--
                }
                ball.style.marginLeft=marginLeft+'px'
                animate(ball,distance,cb)
            }
        },13)
    }
    /*引入promise对象*/
   var Promise=window.Promise
    function promiseAnimate(ball,distance) {
        return new Promise(function (resolve, reject) {
            function _animate() {
                setTimeout(function () {
                    var marginLeft = parseInt(ball.style.marginLeft, 10)
                    if (marginLeft === distance) {
                        resolve()
                    } else {
                        if (marginLeft < distance) {
                            marginLeft++
                        } else {
                            marginLeft--
                        }
                        ball.style.marginLeft = marginLeft+'px'
                        _animate()
                    }
                }, 13)
            }

            _animate();
        })
    }
    /*用romise的方式实现小球的运动*/
    promiseAnimate(ball1,100)
        .then(function () {
            return promiseAnimate(ball2,200)
        })
        .then(function () {
            return promiseAnimate(ball3,300)
        })
        .then(function () {
            return promiseAnimate(ball3,150)
        })
        .then(function () {
            return promiseAnimate(ball2,150)
        })
        .then(function () {
            return promiseAnimate(ball1,150)
        })
</script>

</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值