Angular场景下如何在所有Promise执行完成后再结束Observable
问题根源
- 原代码的
observers.complete()写在了Observable构造函数的回调外部,初始化Observable时就会立即执行,和异步请求逻辑完全脱离 forEach遍历发起的pki.sign都是异步操作,没有统一的全量完成监听逻辑,你直接在observers.next()里传入forEach执行语句没有任何作用,forEach本身返回undefined,相当于你给next传了个空值- 你提到
pki.sign返回Promise但无法用await调用,大概率是这个库返回的是自定义的类Promise对象,没有实现标准ES Promise的then链式调用规范,只暴露了success回调,可以手动包装成标准Promise处理
修复后代码
import { Observable } from 'rxjs'; let pki = new Library(); const thumbprint = '你的业务thumbprint值'; const tokens: string[] = []; // 替换为你的业务tokens数组 const assinaObservable = new Observable<string[]>((observer) => { // 把所有pki.sign调用包装成标准Promise数组 const signPromises: Promise<string>[] = tokens.map((value) => { return new Promise((resolve) => { pki.sign({ thumbprint: thumbprint, token: value }) .success((result: string) => { resolve(result); }); }); }); // 等待所有Promise执行完成后再触发next和complete Promise.all(signPromises) .then((signedList) => { observer.next(signedList); observer.complete(); }) .catch((err) => { // 可选:处理异常场景,可根据业务需求选择单个失败就终止,还是忽略错误返回已成功的结果 observer.error(err); }); }); // 订阅使用示例 assinaObservable.subscribe({ next: (signed) => { // 这里拿到所有签名完成的数组 console.log(signed); }, complete: () => { console.log('全量签名流程结束'); } });
方案说明
- 用
map代替forEach生成所有签名请求的Promise数组,每个请求都手动包了一层标准Promise,通过success回调触发resolve,兼容了第三方库的非标准Promise实现 - 用
Promise.all监听所有请求的完成状态,所有请求都返回结果后才会触发then回调,这时候再给Observable发next和complete,完全避免了提前结束的问题 - 如果业务需要支持单个签名失败也返回其余成功结果,可以在每个包装的Promise里捕获错误,把错误状态和结果一起resolve,最后在then回调里过滤处理即可
内容的提问来源于stack exchange,提问作者AraujoDev
相关产品推荐
相关产品推荐

