簡體   English   中英

如何在Angular中處理異步函數

[英]How to handle async functions in Angular

 //This is a function that is in my data service (in Angular) that basically gets data and puts it in an array getTenantData() { //This is the function that is called by app.component.ts //It's job is to get data from the tenants collection and map it to an array called tenants this.afs //afs is simply what i named the Firebase db in my constructor .collection('tenants') .snapshotChanges() .subscribe(values => { this.tenants = values.map(value => { return { id: value.payload.doc.id, ...value.payload.doc.data() }; }); }); } //Then if I create a function that performs some 'work' on the tenants array in another component like so filterMyArray() { this.ad.tenants.filter(values => { //ad is simply what i called the dataservice in the constructor if (values.id == 'Some Value') { this.filteredArray.push(values); } }); console.log(this.filteredArray); } //This works fine if I call it using some manual 'after load' approach (like clicking a button) //Doesn't work if I call it in ngOnInit for instance as tenants hasn't been populated yet //Throws typeerror cannot read property filter of undefined etc. //So challenge is how do I get the second function to wait for the first //Keep in mind first function is in a service not in the same component as second function 

我一直在遇到需要在構建Angular應用程序時處理異步數據的用例。 我已經采用了許多策略來處理事情(異步管道,ngIf等待某些變量准備就緒等)但我覺得我錯過了一些東西。 以下是最新挑戰的具體內容......我有一個從Firebase填充的陣列。 這是在加載應用程序時通過函數調用完成的。 我們調用數組'sourceArray'

然后,我想在該數組上做一些“工作”,以便在其他組件中播放內容元素。 例如,對該陣列執行“過濾器”並根據這些結果創建新數組。

我一直在遇到的挑戰(這只是最新的例子)是當我調用在sourceArray上執行'其他工作'的函數時,我得到錯誤,說blah blah是未定義的,因為它還沒有完全填充來自firebase 。 所以要簡單地解決這個問題...... - 源變量是從需要一些'時間'的東西填充的 - 只有'在'完全填充之后才能對該源變量進行處理

我已經閱讀了使用生命周期鈎子(即將依賴函數放在源函數之后運行的鈎子中)等等,並且使用該策略的成功有限。 另外值得注意的是,我正在訂閱源陣列中的firebase數據。

我還調查過可能使用async和await但是我真的不明白我將如何應用於這個用例。 如果這還不夠,任何建議都會很感激,並樂意提供更多細節。

// This is how you can await a call from firebase 
// & later do something after call is completed

// write
async function writeData (userId, name, email, imageUrl) {
 await firebase.database().ref('users/' + userId).set({
    username: name,
    email: email,
    profile_picture : imageUrl
  });
  // do something when after is executed
}

// read
async function readData (userId) {
 let response = await firebase.database().ref('/users/' + userId).once('value')
 console.log(response.val())
 // do something after above is executed 
}

首先,您沒有按預期使用filter()方法。 你正在使用它就像你使用map() 你可以做到

filterMyArray() {
 this.filteredArray = this.ad.tenants.filter(values => values.id == 'Some Value');
  console.log(this.filteredArray);
}

對於您主要關心的問題,您可以在服務中設置一個觀察程序,在填充原始數組時過濾掉它。

constructor() {
  this.setupWatcher();
}

setupWatcher() {
  interval(1000).pipe(
        switchMap(() => of(this.ad.tenants)),
        filter(response => response && response.length > 0),
        take(1))
        .subscribe((input: Tenants[]) => {
          //do stuff
          this.filterMyArray(input);
        });
}

接着,

filterMyArray(originalArray: Tenants[]) {
  this.filteredArray = originalArray.filter(values => values.id == 'Some Value');
  console.log(this.filteredArray);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM