确认async-pool中两段Promise代码是否等价及验证测试方法
两段Promise代码的等价性验证与单元测试
等价性结论:二者不等价
核心差异在于iteratorFn的执行时机:
- 第一段代码
const p = Promise.resolve(iteratorFn(item, iterable));:iteratorFn会同步执行,如果它是同步函数,返回值会被直接包装为resolved状态的Promise;如果是异步函数,会立即启动异步逻辑。 - 第二段代码
const p = Promise.resolve().then(() => iteratorFn(item, iterable));:iteratorFn会被放入microtask队列,等当前同步代码执行完毕后才执行,属于异步触发。
验证方式:通过日志顺序判断执行时机
用日志打印可直观验证执行顺序差异:
console.log("1. 开始执行同步代码"); // 测试第一段代码 const syncFn = () => { console.log("2. iteratorFn 同步执行"); return "同步结果"; }; const p1 = Promise.resolve(syncFn()); console.log("3. 第一段代码执行完毕"); console.log("---分割线---"); console.log("4. 开始测试第二段代码"); const p2 = Promise.resolve().then(() => { console.log("5. iteratorFn 在microtask中执行"); return "异步触发结果"; }); console.log("6. 第二段代码执行完毕");
输出顺序:
1. 开始执行同步代码 2. iteratorFn 同步执行 3. 第一段代码执行完毕 ---分割线--- 4. 开始测试第二段代码 6. 第二段代码执行完毕 5. iteratorFn 在microtask中执行
从输出可见:第一段的iteratorFn同步执行,第二段则在所有同步代码跑完后才执行。
单元测试示例(基于Jest)
测试执行时机差异
test("验证两段代码的执行时机差异", (done) => { const executionLog = []; // 测试第一段代码逻辑 executionLog.push("before-p1"); const syncIterator = () => { executionLog.push("sync-iterator-executed"); return "sync-value"; }; const p1 = Promise.resolve(syncIterator()); executionLog.push("after-p1"); // 测试第二段代码逻辑 executionLog.push("before-p2"); const p2 = Promise.resolve().then(() => { executionLog.push("async-triggered-iterator-executed"); return "async-value"; }); executionLog.push("after-p2"); // 等待所有Promise完成后验证日志顺序 Promise.all([p1, p2]).then(() => { expect(executionLog).toEqual([ "before-p1", "sync-iterator-executed", "after-p1", "before-p2", "after-p2", "async-triggered-iterator-executed" ]); done(); }); });
测试异步iteratorFn的结果一致性
如果iteratorFn本身是异步函数(返回Promise),两段代码的最终结果一致,但执行时机仍有差异,可通过以下测试验证:
test("异步iteratorFn的结果一致性", (done) => { const asyncIterator = () => new Promise(resolve => { setTimeout(() => resolve("async-result"), 100); }); const p1 = Promise.resolve(asyncIterator()); const p2 = Promise.resolve().then(() => asyncIterator()); Promise.all([p1, p2]).then(([res1, res2]) => { expect(res1).toBe("async-result"); expect(res2).toBe("async-result"); done(); }); });
内容的提问来源于stack exchange,提问作者jiangyeka
相关产品推荐
相关产品推荐

