如何实现仅保留先后调用的两个同功能异步函数中后调用者的执行结果
解决方案
核心思路
利用闭包维护调用版本号,每次调用时生成唯一版本标记,异步回调执行前判断当前标记是否为最新,仅最后一次调用的回调会真正生效。该方案通过工厂函数生成独立的执行实例,不同实例的版本号互不干扰,可在同页面多场景复用,完全不需要维护全局追踪变量。
通用实现代码
/** * 工厂函数,生成仅最后一次调用生效的异步执行器 * @returns {Function} 执行器函数,接收异步函数和结果回调两个参数 */ function createLastCallExecutor() { // 闭包维护版本号,仅当前执行器实例可访问 let latestCallId = 0; return function (asyncFn, resultCallback) { const currentCallId = ++latestCallId; // 执行传入的异步函数,结果通过参数返回 asyncFn((result) => { // 仅当前调用为最新调用时,才执行结果回调 if (currentCallId === latestCallId) { resultCallback(result); } }) } }
适配你的业务场景
let a = null // 改造原有函数,将执行结果通过回调返回 function function1(callback) { setTimeout(() => { callback(5); }, Math.random() * 100) } function function2(callback) { setTimeout(() => { callback(10); }, Math.random() * 100) } // 为当前业务场景创建独立执行器,多场景可创建多个互不干扰 const executor = createLastCallExecutor(); setInterval(() => { executor(function1, res => a = res); executor(function2, res => a = res); console.log(a); }, 2000)
扩展:适配返回Promise的异步函数
如果你的异步逻辑是用Promise实现的,可以用下面的适配版本:
function createLastPromiseExecutor() { let latestCallId = 0; return async function (promiseFn, resultCallback) { const currentCallId = ++latestCallId; const result = await promiseFn(); if (currentCallId === latestCallId) { resultCallback(result); } } }
原理说明
- 闭包内的
latestCallId变量仅在对应执行器实例内有效,不会污染全局作用域 - 每次调用执行器时版本号自增,每个异步任务会绑定调用时的版本号
- 异步任务完成后,仅当绑定的版本号等于当前最新版本号时,才会执行后续赋值逻辑
- 不同业务场景可单独创建执行器实例,完全互不影响
内容的提问来源于stack exchange,提问作者aryan singh
相关产品推荐
相关产品推荐

