Observable.bindCallback 如果我直接订阅它只有 returns 值
Observable.bindCallback only returns value if I subscribe to it directly
Observable.bindCallback如果我直接订阅的话只有returns值
换句话说,这很好用:
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:
问候
肖恩
如果我明白你想做什么,它应该看起来像这样(显然我没有测试它):
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()
因为我想从 return 由 boundCallback()
编辑的 Observable 中获取值。
此外,在使用 map()
时,您 始终需要 return 一个可以进一步传播的值 。在您的示例中,您没有 returning 任何东西,因此您可以仅使用 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 获取实际值并尝试在您的应用程序中复制相同的逻辑。
找到解决办法了,我是一个Obs太深了:
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;
})
})
Observable.bindCallback如果我直接订阅的话只有returns值 换句话说,这很好用:
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:
问候
肖恩
如果我明白你想做什么,它应该看起来像这样(显然我没有测试它):
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()
因为我想从 return 由 boundCallback()
编辑的 Observable 中获取值。
此外,在使用 map()
时,您 始终需要 return 一个可以进一步传播的值 。在您的示例中,您没有 returning 任何东西,因此您可以仅使用 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 获取实际值并尝试在您的应用程序中复制相同的逻辑。
找到解决办法了,我是一个Obs太深了:
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;
})
})