避免从后台异步请求返回 null



我有一个非常大的请求,需要 15 秒才能返回数据。我想在用户登录时调用该请求,以减少他们转到加载该数据的路由所需的时间(他们可以在完成后到达那里,这将立即向他们显示数据,或者它可能没有完成,但只让他们在那个时候等待几秒钟)。

因此,当用户登录并获得成功时,我会请求大型数据集:

this.getDataService.getAsyncData(data.LinkToken); // This loads request from data service

然后,我在返回时将该数据保存到本地存储中,然后当用户到达从ngOnOnit()发出该请求的路由时,可以检索该数据

getAsyncData(linkToken){ //this is background request that is loading while user navigates through app
this.httpC.get(this.baseUrl + "/AccountInfo/Data?linkToken=" + linkToken + "&deliveryTypeId=" + 0 + "&pickupLocationId=" + 0 + "&paymentTypeId=" + 0).map((res:Response) => res.json()).subscribe(res => {
this.asycCollection = res;
this.globalService.setData(this.asycCollection) //This passes this data to service that stores in local storage
console.log(this.asycCollection);
})
}

然后,该数据可以作为承诺请求从该路由加载时加载的组件返回

//This sets local storage with the data
setData(refillObject:any){ 
this.refillObj = refillObject;
window.localStorage.setItem("refillData", JSON.stringify(this.refillObj))
}
//This gets promise of that background async call
getData(){
let refillInformation:any = window.localStorage.getItem("refillData");
return new Promise<any>((resolve, reject) => resolve(refillInformation));
}

然后从我的路由组件中,我想检索此数据,但仅在它完成加载数据时检索,否则它会返回 null,当然没有任何效果。因此,如果用户快速导航到此页面,则它会返回 null(因为请求尚未完成加载数据)并爆炸,但如果用户在请求完成后返回,则一切都按设计工作。

如何等待并在数据加载完成后获取数据?请记住,这是用户登录时的后台异步请求,我正在从本地存储中检索并且不向 REST Svc 发出新请求。

组件代码:

getAsyncRefills(success){
this.globalService.getData().then(data => { //everything below this blows up if the page is loaded before the data request has finished loading to local storage.
this.orderData = JSON.parse(data);
this.currentDeliveryType = this.orderData.DeliveryTypes.find((item) => 
item.DeliveryTypeId == this.orderData.DeliveryTypeId);
this.currentPaymentArr = this.currentDeliveryType.PaymentTypes;
this.currentPickupLocations = this.currentDeliveryType.PickupLocations;

this.setOptions();
this.buildOrders();
})
}

我会通过以下方式解决这个问题。

我会建立一个有责任的服务

  • 在后端触发繁重查询的执行
  • 将查询结果到达时发出的可观察量公开为公共属性
    • 数据从后端到达后,它使用作为公共属性公开的可观察量发出数据

服务通过依赖关系注入注入到执行登录的组件和需要显示数据的组件中。

登录成功后,执行登录的组件将调用触发查询的服务的方法。

需要显示数据的组件可以使用服务公开为公共属性的可观察量,以便在数据到达后显示数据。有几种方法可以做到这一点。您可以使用 Angular 中的异步管道,它允许您直接在模板中引用可观察量,也可以订阅可观察量,然后使用订阅逻辑中定义的函数填充所需的变量。

对于这样的事情,我不会使用本地存储,而是使用服务(抱歉没有 IDE,所以代码可能并不完美)。

@Injectable()
export class ExpensiveDataStore {
private expensiveData_: ConnectableObservable<ExpensiveThing>;
private connection: Subscription;
get expensiveData(): Observable<ExpensiveThing> {
if(!this.expensiveData_) {
throw Error('Must initialize store first!');
}
return this.expensiveData_;
}
initialize() {
this.expensiveData_ = this.goFetchExpensiveData().publishLast();
this.connection = this.expensiveData.connect();
}
void reset() {
this.connection.unsubscribe();
this.connection = this.expensiveData.connect();
}
}

在您的app.component.ts或某些高级组件中,您可以调用initialize()。 在需要数据的组件中,您可以订阅expensiveData.

最新更新