When.js 核心 API 详解与最佳实践

When.js 核心 API 详解与最佳实践

when A solid, fast Promises/A+ and when() implementation, plus other async goodies. when 项目地址: https://gitcode.com/gh_mirrors/wh/when

前言

When.js 是一个轻量级的 Promises/A+ 实现库,提供了丰富的异步编程工具集。本文将深入解析 When.js 的核心 API 及其使用场景,帮助开发者更好地掌握 Promise 编程范式。

核心概念

Promise 是什么

Promise 是对异步操作结果的代理对象,它代表一个可能现在、也可能未来才可用的值。通过 Promise,我们可以用同步的编程风格来处理异步操作,避免回调地狱。

核心 API 解析

1. 基础创建与转换

when() 函数

when() 是 When.js 的核心入口函数,用于将任意值转换为可信 Promise:

// 将值转换为已完成的 Promise
const promise1 = when(42); 

// 将其他 Promise 转换为 When.js Promise
const promise2 = when($.ajax('/data')); 

// 带转换函数的用法
const promise3 = when(value, x => x * 2);

最佳实践

  • 使用 when() 包装不确定是否为 Promise 的值
  • 在与其他 Promise 库混用时,用 when() 进行标准化
when.try() 方法

安全执行函数并返回 Promise:

// 安全执行可能抛出异常的函数
when.try(() => JSON.parse(jsonStr))
    .catch(e => console.error("解析失败", e));

特点

  • 自动捕获同步异常
  • 支持 Promise 参数自动解包
  • 替代 new Promise 的更简洁方式
when.lift() 方法

创建 Promise 化函数:

const safeParse = when.lift(JSON.parse);

// 可重复使用
safeParse('{"a":1}').then(console.log);
safeParse('invalid').catch(console.error);

适用场景

  • 将现有同步函数改造为 Promise 风格
  • 创建可复用的安全函数

2. Promise 组合

when.join() 方法

合并多个 Promise 为一个:

when.join(getUser(), getProfile())
    .then(([user, profile]) => {
        // 处理合并结果
    });

对比 when.all()

  • join 接受多个参数
  • all 接受数组参数
  • 功能等价,按场景选择更合适的 API
when.promise() 构造函数

显式创建 Promise:

const promise = when.promise((resolve, reject) => {
    asyncOperation((err, result) => {
        if (err) reject(err);
        else resolve(result);
    });
});

注意事项

  • 优先考虑 when.trywhen.lift
  • 仅在不适合使用上述方法时才用此 API

3. 状态控制

when.resolve() 与 when.reject()

快速创建已解决/已拒绝的 Promise:

// 快速返回成功结果
function cachedData() {
    return cache.hasData 
        ? when.resolve(cache.data)
        : fetchData();
}

// 快速返回错误
function validate(input) {
    return !input 
        ? when.reject(new Error("输入不能为空"))
        : process(input);
}

Promise 实例方法

1. 结果处理

then() 与 done() 对比

| 方法 | 返回值 | 错误处理 | 适用场景 | |------|--------|----------|----------| | then() | 新 Promise | 链式捕获 | 转换/组合 Promise | | done() | undefined | 抛出异常 | 最终消费结果 |

示例对比

// 转换场景 - 使用 then
function getProcessedData() {
    return fetchData()
        .then(transform)
        .then(validate);
}

// 消费场景 - 使用 done
getProcessedData().done(
    result => display(result),
    error => showError(error)
);
spread() 方法

展开数组结果:

fetchMultipleItems().spread((item1, item2) => {
    // 直接使用解构参数
});

等价于

fetchMultipleItems()
    .then(items => when.all(items))
    .then(([item1, item2]) => {...});

2. 错误处理

catch() 高级用法

条件错误捕获:

apiCall()
    .catch(NetworkError, e => retry())
    .catch(ValidationError, e => log())
    .catch(e => fallback());

优势

  • 比传统 try/catch 更清晰
  • 支持错误类型分类处理
  • 保持错误处理代码靠近可能抛出错误的代码
finally() 方法

资源清理:

let resource;
getResource()
    .then(r => { resource = r; })
    .finally(() => {
        if (resource) resource.release();
    });

特点

  • 无论成功失败都会执行
  • 不影响 Promise 链的结果传递
  • 适合执行清理操作

高级模式

Promise 折叠 (fold)

组合两个 Promise:

// 使用现有函数组合 Promise
const total = price.fold(add, tax);

// 等价于
const total = when.join(price, tax)
    .then(([p, t]) => p + t);

优势

  • 复用现有二元函数
  • 避免临时数组创建
  • 更直观的表达意图

进度通知 (已废弃)

// 旧版进度通知 (已废弃)
uploadFile()
    .progress(p => updateProgressBar(p))
    .then(finish);

替代方案

  • 使用事件或 Observable
  • 拆分多个 Promise 表示不同阶段

最佳实践总结

  1. 错误处理原则

    • 要么 return Promise 传递错误
    • 要么 done() 处理错误
  2. API 选择指南

    • 简单转换:then()
    • 错误处理:catch()
    • 资源清理:finally()
    • 结果消费:done()
  3. 性能优化

    • 避免不必要的 Promise 包装
    • 提前创建重用 lifted 函数
    • 使用 join/all 并行执行独立操作
  4. 代码可读性

    • 保持 Promise 链垂直对齐
    • 命名中间 Promise 变量
    • 合理使用缩进表达层级

通过掌握这些核心 API 和模式,开发者可以构建出健壮、可维护的异步 JavaScript 应用。

when A solid, fast Promises/A+ and when() implementation, plus other async goodies. when 项目地址: https://gitcode.com/gh_mirrors/wh/when

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尚虹卿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值