我遇到了一些Ionic 3应用程序代码的问题。
基本上,我有一个所有具有唯一ID的对象列表。必须通过GET
请求发送每个对象的唯一ID,以便我们可以从服务器获取每个对象的相应数据。这必须基于每个对象完成;我无法将它们捆绑到一个请求中,因为没有API端点。
因此,对象都存储在一个数组中,因此我一直在尝试遍历数组并为每个对象调用提供程序。请注意,提供程序正在返回一个observable。
由于提供程序是一个异步函数,因此在循环结束之前,promise将解析,除非我超出promise解析。这违背了承诺的全部要点。
我应该采取什么样的正确方法,以便在promise解决之前完成循环提供程序调用?
如果我在循环完成时有内心的承诺解决,它是否也会过早解决?
我还读到,打开一堆可观察量是不好的。我是否应该使用toPromise()
将每个observable作为承诺返回?
以下是构建数据的代码:
asyncBuildData() {
var promise = new Promise((resolve, reject) => {
let completedRequests = 0;
for (let i = 0; i < 10; i++) {
this.provider.getStuffById(listOfStuff[i].id).subscribe(val => {
list.push(val)
completedRequests++;
})
}
console.log('cp', completedRequests); // completedRequests = 0
setTimeout(() => {
console.log('cp', completedRequests); // completedRequests = 10
let done = true;
if (done) {
resolve('Done');
} else {
reject('Not done');
}
}, 1500)
})
return promise;
}
提供商代码:
getStuffById(stuffId) {
let url = url + stuffId;
return this.http.get(url)
.map(res => res.json());
}
答案 0 :(得分:1)
即使您无法将它们捆绑到一个请求中,您仍然可以将它们捆绑到一个可观察对象中,并使用.forkJoin()
并行触发这些请求:< / p>
buildData$() {
let parallelRequests = listOfStuffs.map(stuff => this.provider.getStuffById(stuff.id));
return Observable.forkJoin([...parallelRequests]);
}
然后在您的组件中,您可以致电:
buildData$.subscribe(val=>{
//val is an array of all the results of this.provider.getStuffById()
list =val;
})
请注意,Obersvable.forkJoin()
将在发出任何值之前完成所有请求。
答案 1 :(得分:0)
如果我理解正确,那么以下代码可以帮助您顺利进行。这将为数组中的每个元素一次执行一个promise。
var ids = [1,2,3,4,5];
ids.reduce(function (promise, id) {
return promise.then(function () {
let url = url + id;
return this.http.get(url)
.map(res => res.json());
});
}, Promise.resolve()).then(function(last) {
// handle last result
}, function(err) {
// handle errors
});
我用jQuery帖子对它进行了测试,然后用你的Ionic替换它。如果失败,请告诉我。