JavaScript异步回调的Promise模式封装实例

作者:纸飞机

时间:2026-10-28

浏览:635

本文探讨JavaScript异步操作中回调函数带来的代码耦合与复杂性,通过easy.js库演示如何封装普通函数为Promise实例。文章详细讲解了Promise的三种状态、then方法的用法,以及利用when方法处理多个并发Ajax请求的技巧,旨在提升代码的可维护性与优雅度。

文章目录

异步回调的挑战与Promise封装优势

随着网页交互日益复杂,JavaScript 中的异步操作变得愈发普遍。以常见的 Ajax 请求为例,开发者需要在请求完成后执行响应操作。由于请求通常是异步的,用户在等待期间仍可执行其他操作,页面不会被阻塞,这种体验对用户十分友好。然而,对于开发者而言,大量处理此类异步操作却并不轻松。异步请求完成后的逻辑必须预先定义在回调函数中,并在请求结束时调用。这种非线性的异步编程模式让许多开发者感到不适,不仅增加了代码的耦合度和复杂性,还导致代码组织不够优雅,严重降低了可维护性。若情况更为复杂,例如一个操作需等待多个异步 Ajax 请求全部完成才能执行,便会出现回调函数层层嵌套的情况,若嵌套层数过多,代码将变得难以维护。

以下是一个常见的异步函数示例:

var showMsg = function(){
setTimeout(function(){
alert( 'hello' );
}, 5000 );
};

若需为该函数添加回调支持,常规做法如下:

以下代码展示了传统方式:

var showMsg = function( callback ){
setTimeout(function(){
alert( 'hello' );
// 此处添加回调
callback();
}, 5000 );
};

若采用 easy.js 提供的 Promise 模式,添加回调的方式将更加优雅,但前提是将原函数封装为 Promise 实例。

以下是使用 easy.js Promise 的封装示例:

var showMsg = function(){
// 构造promise实例
var promise = new E.Promise();
setTimeout(function(){
alert( 'hello' );
// 改变promise的状态
promise.resolve( 'done' );
}, 5000 );
// 返回promise实例
return promise;
};

Promise实例的创建与状态管理

将一个普通函数封装为 Promise 实例包含三个关键步骤:首先,在函数内部创建 Promise 实例;其次,在函数执行完毕后,将 Promise 的状态更改为已完成(resolved);最后,返回该 Promise 实例。每个 Promise 实例拥有三种状态:pending(未完成)、resolved(已完成/成功)和 rejected(已拒绝/失败)。接下来介绍如何添加回调。

添加回调的代码如下:

showMsg().then(function( str ){
// 回调添加到这里来了
callback( str );
});

使用then处理单请求回调

这样,回调函数与原异步函数实现了彻底分离,从代码组织角度看,结构更加清晰优雅。resolve 方法接收一个参数,该参数可轻松传递给通过 then 方法添加的回调函数中。对于 Ajax 请求,easy.js 直接将 ajax 方法封装为 Promise 对象,允许直接添加 then 方法来处理回调。

以下是 Ajax 请求的 Promise 封装示例:

E.ajax({
url : 'test1.php',
type : 'GET'
})
.then(function(){
// 添加请求成功的回调
}, function(){
// 添加请求失败的回调
});

利用when处理多并发请求

then 方法接受两个函数作为参数:第一个函数用于处理已完成(成功)的情况,第二个函数用于处理已拒绝(失败)的情况。若遇到前文提到的多个 Ajax 请求场景,则需使用 when 方法。该方法可接收多个 Promise 实例作为参数。

以下是 when 方法的使用示例:

var requests = E.when(E.ajax({
url : 'test1.php',
type : 'GET'
}), E.ajax({
url : 'test2.php',
type : 'GET'
}));
requests.then(function( arg1, arg2 ){
 console.log( 'success:' + arg1[0] + arg2[0] );
}, function( arg1, arg2 ){
 console.log( 'failure:' + arg1 + arg2 );
});

when 方法将多个 Promise 实例存入数组,仅当数组中所有 Promise 实例均处于已完成状态时,才执行成功的回调;一旦其中任何一个实例处于已拒绝状态,则立即执行失败的回调。

Promise 模式是 CommonJS 规范的一部分。许多主流 JavaScript 库均提供了相应的实现,例如 jQuery 和 Dojo 中通过 Deferred 对象来实现这些功能。在此需指出,jQuery 的 Deferred 模块虽然内部使用广泛,但用户实际使用率较低,这与其相对复杂的使用方式有一定关系。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章