JavaScript异步编程-Promise模式

本文深入探讨Promise的概念、状态变化及其在异步编程中的应用,通过示例展示如何利用Promise简化代码结构,提高异步操作的可读性和可维护性。重点介绍了Promise的实现方式、关键属性、方法及特性,以及与现代JavaScript库的整合,旨在帮助开发者掌握这一核心异步编程技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Promise是个对象也是个规范,Promise 对象用于延迟(deferred) 计算和异步(asynchronous ) 计算.。一个Promise对象代表着一个还未完成,但预期将来会完成的操作。

概念

三个状态

未完成(pending)
已完成(fulfilled)
失败(rejected)

pending状态的promise对象既可转换为带着一个成功值的fulfilled 状态,也可变为带着一个失败信息的 rejected 状态。当状态发生转换时,promise.then绑定的方法(函数句柄)就会被调用。(当绑定方法时,如果 promise对象已经处于 fulfilled 或 rejected 状态,那么相应的方法将会被立刻调用, 所以在异步操作的完成情况和它的绑定方法之间不存在竞争条件。)

以CommonJS Promise/A 标准为例,promise对象上的then方法负责添加针对已完成和拒绝状态下的处理函数。then方法会返回另一个promise对象,以便于形成promise管道,这种返回promise对象的方式能够支持开发人员把异步操作串联起来,如then(resolved, rejected)。resolved回调函数在promise对象进入完成状态时会触发,并传递结果,rejected函数会在拒绝状态下调用。

A与A+规范

A+通过thenable来区分promise对象
A+定义onFulfilled/onRejected必须作为函数来调用,而且调用过程必须是一步的
A+严格定义了then方法链式调用时onFulfilled/onRejected的调用顺序

Promise库

bluebird
Q
then.js

简单的示例

promise会使代码更易读易写

<!doctype html>
<html>
<head>
    <title>promise</title>
    <style>
    div{
        width:100px;
        height:100px;
        border-radius: 50px;
        background-color: red;
    }
    </style>
</head>
<body>
<div style="margin-left:0px;"></div>
<div style="margin-left:0px;"></div>
<div style="margin-left:0px;"></div>
</body>
<script>
var balls = document.getElementsByTagName("div");
console.log(balls.length);
var ball1 = balls[0];
var ball2 = balls[1];
var ball3 = balls[2];


/*不用promise时的异步调用*/
function animate(ball,distance,callback){
    setTimeout(function(){
        var marginLeft = parseInt(ball.style.marginLeft,10);
        console.log(ball.style.marginLeft);
        if(marginLeft>=distance){
            callback&&callback();//First it checks to ensure that callback is defined (more accurately, that it is a truthy value). Then, if it is, it calls that function.
        }else{
             marginLeft++;
             ball.style.marginLeft = marginLeft+'px';
             animate(ball,distance,callback);
        }
    },13);  
}

animate(ball1,200,function(){
    animate(ball2,200,function(){
        animate(ball3,200);
    });
});

/*使用promise的*/
var Promise = window.Promise;

function promise_animate(ball,distance){
    return new Promise(function(resolve,reject){
        function _animate(){
            setTimeout(function(){
            var marginLeft = parseInt(ball.style.marginLeft,10);
            console.log(ball.style.marginLeft);
            if(marginLeft>=distance){
                resolve&&resolve();
            }else{
                 marginLeft++;
                 ball.style.marginLeft = marginLeft+'px';
                 _animate();
            }
        },13);  
        };
         _animate();
    });
}

promise_animate(ball1,400)
    .then(function(){promise_animate(ball2,400);})
        .then(function(){promise_animate(ball3,400);});
</script>
</html>

Promise实现

mozilla

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise

属性

Promise.length
长度属性,其值为 1 (构造器参数的数目).
Promise.prototype
表示 Promise 构造器的原型.

方法

Promise.all(iterable)
返回一个promise对象,当iterable参数里所有的promise都被解决后,该promise也会被解决。
Promise.race(iterable)
当iterable参数里的任意一个子promise被成功或失败后,父promise马上也会用子promise的成功返回值或失败详情作为参数调用父promise绑定的相应句柄,并返回该promise对象。
Promise.reject(reason)
调用Promise的rejected句柄,并返回这个Promise对象。
Promise.resolve(value)
用成功值value解决一个Promise对象。如果该value为可继续的(thenable,即带有then方法),返回的Promise对象会“跟随”这个value,采用这个value的最终状态;否则的话返回值会用这个value满足(fullfil)返回的Promise对象。

Promise原型

属性

Promise.prototype.constructor
返回创建了实例原型的函数. 默认为 Promise 函数.

方法

Promise.prototype.catch(onRejected)
添加一个否定(rejection) 回调到当前 promise, 返回一个新的promise。如果这个回调被调用,新 promise 将以它的返回值来resolve,否则如果当前promise 进入fulfilled状态,则以当前promise的肯定结果作为新promise的肯定结果.(相当于Promise.prototype.then(undefined, onRejected))
Promise.prototype.then(onFulfilled, onRejected)
添加肯定和否定回调到当前 promise, 返回一个新的 promise, 将以回调的返回值 来resolve.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值