简体   繁体   中英

Javascript Promise looping multiple times

I have a Javascript promise that returns a list of items.

findMessages(chatItem: any): Promise<any[]> {
    return new Promise<any[]>((resolve) => {
        let items: any[] = [];
        let promiseArray: Promise<any>[] = [];
        this.storage.keys().then((keys: string[]) => {
            for (let i: number = 0; i < keys.length; i++) {
                if (keys[i] && keys[i].startsWith(this.me.uid + 'message/')) {
                    let promise: Promise<any> = this.storage.get(keys[i])
                    promise.then((data: string) => {
                        let item: any = JSON.parse(data);
                        if ((item && item.memberId1 === chatItem.memberId1 && item.memberId2 === chatItem.memberId2)
                            || (item && item.memberId1 === chatItem.memberId2 && item.memberId2 === chatItem.memberId1)) {
                            items.push(item);
                        }
                    });
                    promiseArray.push(promise);
                }
            }
            Promise.all(promiseArray).then(() => {
                resolve(items);
            });
        });
    });
}

This Promise is called below.

findMessages(chatItem: any): Observable<any[]> {
    return Observable.create((observer) => {
        this.firebaseDataService.findMessages(chatItem).forEach(firebaseItems => {
            this.localDataService.findMessages(chatItem).then((localItems: any[]) => {
                let mergedItems: any[] = this.arrayUnique(firebaseItems.concat(localItems), false);
                mergedItems.sort((a, b) => {
                    return parseFloat(a.negativtimestamp) - parseFloat(b.negativtimestamp);
                });
                if (this.me && mergedItems && mergedItems[0] && this.me.uid === mergedItems[0].memberId2) {
                    this.updateChatWithMessage(chatItem, mergedItems[0], false);
                }
                observer.next(mergedItems);
            });
        });
    });
}

Problem

After the promise call, I expect the following line to only be called once :

let mergedItems: any[] = this.arrayUnique(f....

However, if I place a breakpoint on this line, it is called multiple times when returning from the promise. It gets called the amount of times equal to the number of items returned from the promise ( localitems ). As if it's looping on localitems .

I have probably structured my code incorrectly, any advise would be appreciated.

Thanks

As you aren't using the firebase item as an argument in retrieving the promise you can make the call that returns a promise before you run the for each loop. I'm guessing your problem is that as the promise is inside the for each loop it is firing off a load of promises that are being resolved for each firebase item.

findMessages(chatItem: any): Observable<any[]> {
    return Observable.create((observer) => {
            this.localDataService.findMessages(chatItem).then((localItems: any[]) => {
        this.firebaseDataService.findMessages(chatItem).forEach(firebaseItems => {
                let mergedItems: any[] = this.arrayUnique(firebaseItems.concat(localItems), false);
                mergedItems.sort((a, b) => {
                    return parseFloat(a.negativtimestamp) - parseFloat(b.negativtimestamp);
                });
                if (this.me && mergedItems && mergedItems[0] && this.me.uid === mergedItems[0].memberId2) {
                    this.updateChatWithMessage(chatItem, mergedItems[0], false);
                }
                observer.next(mergedItems);
            });
        });
    });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM