Angular中通过回调函数格式化API响应遇mergeMap报错,求解决
问题分析与解决方案
这个问题我之前也碰到过,核心原因是:xml2js.parseString是基于回调的异步函数,而mergeMap要求你返回一个Observable、Promise、数组或可迭代对象,但你当前的写法里,mergeMap实际拿到的是parseString的返回值(它本身返回undefined),并不是回调里的result,这就导致RxJS抛出了类型错误。
下面给你两种可行的解决方式:
方式一:将回调包装成Promise(最直观)
RxJS可以自动把Promise转换为Observable,所以我们只需要把parseString的回调逻辑封装成Promise即可:
this.http.get('https://some.com/questions.xml', {headers, responseType: 'text'}) .pipe( mergeMap(res => { return new Promise((resolve, reject) => { xml2js.parseString(res, { explicitArray: false }, (error, result) => { if (error) { reject(new Error(error)); } else { console.log(result); resolve(result); } }); }); }) ) .subscribe(data => { console.log("response", data); // 这里就能拿到解析后的JSON了 }, error => { console.log(error); });
方式二:使用RxJS的fromCallback操作符
RxJS提供了fromCallback工具,专门用来把回调风格的函数转换成Observable,适合更"RxJS原生"的写法:
首先需要导入操作符:
import { fromCallback } from 'rxjs/internal/observable/fromCallback';
然后修改代码:
this.http.get('https://some.com/questions.xml', {headers, responseType: 'text'}) .pipe( mergeMap(res => { // 把parseString包装成Observable生成函数 const parseXml$ = fromCallback((xml, options, callback) => xml2js.parseString(xml, options, callback) ); // 传入参数并返回Observable return parseXml$(res, { explicitArray: false }); }) ) .subscribe(data => { console.log("response", data); }, error => { console.log(error); });
额外提示
注意Angular新版本中,推荐把操作符放在pipe()方法里调用(就像上面的写法),你原来直接链式调用.mergeMap()的方式是RxJS旧版本的写法,虽然可能兼容,但更规范的是用pipe包裹操作符。
内容的提问来源于stack exchange,提问作者Robin Joseph
相关产品推荐
相关产品推荐

