promise本身不提供原子性,但可通过链式调用、错误冒泡、统一异常处理及手动补偿回滚模拟逻辑原子性:任一步失败则中断后续执行,并支持逆序撤销已生效副作用。

Promise 本身不提供“原子性”语义(像数据库事务那样失败则全部回滚),但可以通过链式调用、错误冒泡、统一异常处理和手动回滚逻辑,模拟多个异步步骤的逻辑原子性:即所有步骤要么全部成功,要么在任一步失败时停止执行,并可选择性清理已产生的副作用。
用 Promise 链保证执行顺序与中断机制
Promise 链天然具备“短路”特性:任意一个 .then() 中抛出错误或返回被 reject 的 Promise,后续 .then() 就不会执行,控制权交由最近的 .catch()。
例如完成「创建订单 → 扣减库存 → 发送通知」三个步骤:
createOrder()
.then(order => deductInventory(order.id))
.then(result => sendNotification(result.orderId))
.then(() => console.log('全部成功'))
.catch(err => {
console.error('某步失败,流程终止:', err);
// 此处可触发补偿逻辑(见下文)
});
只要其中任一函数返回 rejected Promise 或 throw 错误,后续步骤自动跳过。
Java Linux版下载入口,提供 Oracle JDK 26.0.2 官方 Linux 安装包、Java 环境配置、JDBC 数据库连接和 Java 服务端开发相关信息。
手动实现补偿(回滚)以逼近原子性
真正的原子性需要在失败后撤销前面已完成的操作。这需显式编写补偿函数,常见模式是“记录前序状态 + 失败时调用反向操作”:
- 每步成功后,把关键数据(如订单 ID、库存变更量)暂存到闭包或对象中
- 在
.catch()中,按逆序调用对应的撤销函数(如删除订单、恢复库存) - 补偿操作自身也应返回 Promise 并做错误防护,避免补偿失败导致状态更混乱
let state = {};
createOrder().then(order => {
state.order = order;
return deductInventory(order.id);
}).then(inventoryResult => {
state.inventory = inventoryResult;
return sendNotification(state.order.id);
}).catch(err => {
console.error('流程中断:', err);
return rollback(state).catch(rollbackErr => {
console.warn('回滚也失败了:', rollbackErr);
});
});
用 async/await + try/catch 提升可读性与控制力
相比纯链式写法,async/await 更容易组织补偿逻辑和局部变量管理:
async function executeAtomicFlow() {
let order, inventoryResult;
try {
order = await createOrder();
inventoryResult = await deductInventory(order.id);
await sendNotification(order.id);
console.log('全流程成功');
} catch (err) {
console.error('出错:', err);
if (order && !inventoryResult) {
await cancelOrder(order.id); // 只创建了订单,未扣库存 → 仅删订单
} else if (order && inventoryResult) {
await cancelOrder(order.id);
await restoreInventory(inventoryResult.changeId); // 已扣库存 → 补偿恢复
}
}
}
进阶:封装成可复用的原子任务工具
可抽象一个 atomic 函数,接收步骤数组和对应的回滚函数数组,自动执行与回滚:
function atomic(steps, rollbacks) {
const results = [];
return steps.reduce((promise, step, i) => {
return promise.then(() => step()).then(res => {
results[i] = res;
return res;
});
}, Promise.resolve())
.catch(err => {
// 逆序执行已注册的回滚函数(只对已成功步骤)
const rollbackPromises = rollbacks.slice(0, results.length)
.map(fn => fn && fn()).filter(p => p);
return Promise.allSettled(rollbackPromises).then(() => { throw err; });
});
}
// 使用
atomic(
[createOrder, () => deductInventory(123), () => sendNotification(123)],
[null, () => restoreInventory(123), null]
);
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










