如何从多个observable获取对象响应?
我的史诗喜欢这个:
export function metaDataEpic(action$: ActionsObservable<metaDataActions>) {
return action$.ofType(META_DATA_REQUEST)
.mergeMap((action: metaDataActions) => {
const { language } = action;
return Observable.merge(
Observable.fromPromise(couriersApi().then(r => r.json())),
Observable.fromPromise(itemCategoriesApi({ language }).then(r => r.json())),
Observable.fromPromise(airportsApi().then(r => r.json())))
.flatMap(res => {
console.log(res);
return Observable.of(getMetaDataSuccess({}))
});
});
}
我需要的是传递我的函数getMetaDataSuccess()
一个对象,其中包含来自courierApi()
,itemCategoriesApi()
和airportsApi()
的回复getMetaDataSuccess({ couriers, items, airports })
,但首先我需要等待所有3个承诺完成并以某种方式将对象组合作为响应。
我的代码现在所做的是打印来自API的响应,从而调用getMetaDataSuccess
3次。 enter code here
答案 0 :(得分:2)
听起来你想要这样的东西。
export function metaDataEpic(action$: ActionsObservable<metaDataActions>) {
return action$.ofType(META_DATA_REQUEST)
.flatMap(({language}) => Promise.all([
couriersApi(),
itemCategoriesApi({language}),
airportsApi()
].map(p => p.then(r => r.json()))
)
.then(([couriers, items, airports]) => ({couriers, items, airports}))
)
.do(console.log)
.map(getMetaDataSuccess);
}
flatMap
aka mergeMap
可以直接在Promise和Arraylike值上运行。这里我们使用Promise.all
来等待多个Promises的结果。 Promise.all
返回一个Promise,它解析为一个数组,其中每个元素都是输入数组中相应项的结果。我们将这个数组转换为一个对象并传递它。
这里的虚拟数据证明它有效。
function couriersApi() {
return Promise.resolve({
json: () => [{
name: 'x',
id: 1
}, {
name: 'y',
id: 2
}]
});
}
function airportsApi() {
return Promise.resolve({
json: () => [{
name: 'ORF',
id: 1
}, {
name: 'JFK',
id: 2
}]
});
}
function itemCategoriesApi({language}) {
return Promise.resolve({
json: () => [{
name: 'a',
language: 'German'
},
{
name: 'b',
language: 'English'
},
].filter(c => c.language === language)
});
}
const META_DATA_REQUEST = undefined;
const action$ = {
ofType: () => Rx.Observable.of({
language: 'English'
})
};
metaDataEpic(action$)
.subscribe();
function getMetaDataSuccess(o) {
console.log(o.couriers);
console.log(o.items);
console.log(o.airports);
}
function metaDataEpic(action$) {
return action$.ofType(META_DATA_REQUEST)
.flatMap(({
language
}) => Promise.all([
couriersApi(),
itemCategoriesApi({
language
}),
airportsApi()
].map(p => p.then(r => r.json())))
.then(([couriers, items, airports]) => ({
couriers,
items,
airports
}))
)
.do(console.log)
.map(getMetaDataSuccess);
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.js"></script>
&#13;
答案 1 :(得分:1)
我脑子里有两个解决方案,你可以试试它们是否符合你的情况:
export function metaDataEpic(action$: ActionsObservable<metaDataActions>) {
return action$
.ofType(META_DATA_REQUEST)
.mergeMap((action: metaDataActions) => {
const {language} = action;
Promise.all(
[couriersApi(), itemCategoriesApi({language}), airportsApi()].map(p =>
p.then(r => r.json())
)
)
.then(([couriers, items, airports]) => {
return Observable.of(getMetaDataSuccess({couriers, items, airports}));
})
.catch(e => {
return Observable.of(getMetaDataFail(e));
});
});
}
或
$a = Get-ChildItem C:\tejasoft -recurse | Where-Object {$_.PSIsContainer -eq $True -and ($_.GetDirectories().Count -eq 0)}
$path = $a | Where-Object {$_.GetFiles().Count -eq 0} | foreach {$_.FullName}
$a | Where-Object {$_.GetFiles().Count -eq 0} | foreach {$_.FullName}|ForEach-Object -Process {New-Item -Path $path -Name ".keep" -Value "Test Value" -ItemType File }