如果直接订阅它,Observable.bindCallback只返回值 换句话说,这很好用:
return this.store.select(store => store.appDb.appBaseUrl)
.take(1)
.mergeMap(baseUrl => {
const url = `${baseUrl}?command=GetCustomers&resellerUserName=aaa&resellerPassword=bbbb`;
return this.http.get(url)
.map(res => {
var xmlData = res.text()
const boundCallback = Observable.bindCallback(this.processXml, (xmlData: any) => xmlData);
return boundCallback(this, xmlData)
.subscribe((x) => {
return x;
});
})
})
然而我需要避免订阅,因为我在@effect
内部运行,我自动为我订阅,所以我运行:
return this.store.select(store => store.appDb.appBaseUrl)
.take(1)
.mergeMap(baseUrl => {
const url = `${baseUrl}?command=GetCustomers&resellerUserName=aaa&resellerPassword=aaa`;
return this.http.get(url)
.map(res => {
var xmlData = res.text()
const boundCallback = Observable.bindCallback(this.processXml, (xmlData: any) => xmlData);
var d:any = boundCallback(this, xmlData)
return d;
}).map(d=>{console.log(d)})
})
但现在我得到的是:
,而不是获得一个值这是d:
问候
肖恩
答案 0 :(得分:2)
如果我明白你想做什么,它应该看起来像这样(显然我没有测试它):
return this.store.select(store => store.appDb.appBaseUrl)
.take(1)
.mergeMap(baseUrl => {
const url = `${baseUrl}?command=GetCustomers&resellerUserName=aaa&resellerPassword=aaa`;
return this.http.get(url)
.mergeMap(res => {
var xmlData = res.text()
const boundCallback = Observable.bindCallback(this.processXml, (xmlData: any) => xmlData);
return boundCallback(this, xmlData)
}).do(d => console.log(d))
})
我使用mergeMap()
因为我想从boundCallback()
返回的Observable中获取值。
使用map()
时,始终需要返回值进一步传播的值。在您的示例中,您不会返回任何内容,因此您只需使用do()
即可查看打印的值。
编辑:
因此,这是您尝试做的简化版本。
class A {
private processXml(context, xmlData, cb) {
context.parseString(xmlData, {attrkey: 'attr'}, function (err, result) {
if (err || !result) return cb(null); return cb(result);
})
}
private parseString(str, _, cb) {
return cb(null, str);
}
private mockHttpGet() {
return Rx.Observable.of({
text: () => {
return 'abc';
}
});
}
test() {
return this.mockHttpGet()
.mergeMap(res => {
var xmlData = res.text();
const boundCallback = Rx.Observable.bindCallback(this.processXml, (xmlData: any) => xmlData);
return boundCallback(this, xmlData)
}).do(d => console.log(d))
}
}
let a = new A();
a.test().subscribe(val => console.log('subscribed result', val));
查看现场演示:https://jsbin.com/reweraw/2/edit?js,console
此演示打印:
abc
subscribe abc
BoundCallbackObservable
(这也适用于运营商)在您订阅它们之前不做任何事情。这就是为什么在调试器中你只看到原始数据。
我的演示工作正如您所希望的那样,请查看我如何使用mergeMap()
从嵌套的Observable中获取实际值,并尝试在您的应用程序中复制相同的逻辑。
答案 1 :(得分:0)
return this.store.select(store => store.appDb.appBaseUrl)
.take(1)
.mergeMap(baseUrl => {
const url = `${baseUrl}?command=GetCustomers&resellerUserName=reseller@ms.com&resellerPassword=XXXX`;
return this.http.get(url)
.map(res => {
return res.text()
}).flatMap(jData=>{
const boundCallback = Observable.bindCallback(this.processXml, (xmlData: any) => xmlData);
return boundCallback(this, jData)
}).map(businessData=>{
return businessData;
})
})