Skip to content

Commit

Permalink
feat: added promise with limit logic
Browse files Browse the repository at this point in the history
  • Loading branch information
ioanmo226 committed May 21, 2024
1 parent d4b2b95 commit 88e99a0
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Catch } from '../../../../js/common/platform/catch.js';
import { GmailParser } from '../../../../js/common/api/email-provider/gmail/gmail-parser.js';
import { InboxView } from '../inbox.js';
import { Lang } from '../../../../js/common/lang.js';
import { Str } from '../../../../js/common/core/common.js';
import { Str, promiseAllWithLimit } from '../../../../js/common/core/common.js';
import { Ui } from '../../../../js/common/browser/ui.js';
import { ViewModule } from '../../../../js/common/view-module.js';
import { Xss } from '../../../../js/common/platform/xss.js';
Expand All @@ -18,7 +18,10 @@ export class InboxListThreadsModule extends ViewModule<InboxView> {
try {
const { threads } = await this.view.gmail.threadList(labelId);
if (threads?.length) {
await Promise.all(threads.map(t => this.renderInboxItem(t.id)));
await promiseAllWithLimit(
threads.map(t => () => this.renderInboxItem(t.id)),
3
);
} else {
Xss.sanitizeRender('.threads', `<p>No encrypted messages in ${Xss.escape(labelId)} yet. ${Ui.retryLink()}</p>`);
}
Expand All @@ -39,7 +42,7 @@ export class InboxListThreadsModule extends ViewModule<InboxView> {
}
};

private renderInboxItem = async (threadId: string) => {
private renderInboxItem = async (threadId: string): Promise<void> => {
this.inboxThreadItemAdd(threadId);
const threadItem = $('.threads #' + this.threadListItemId(threadId));
try {
Expand Down
7 changes: 5 additions & 2 deletions extension/js/common/api/email-provider/gmail/gmail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import { AddrParserResult, BrowserWindow } from '../../../browser/browser-window.js';
import { ChunkedCb, ProgressCb, EmailProviderContact } from '../../shared/api.js';
import { Dict, Str, Value } from '../../../core/common.js';
import { Dict, Str, Value, promiseAllWithLimit } from '../../../core/common.js';
import { EmailProviderApi, EmailProviderInterface, Backups } from '../email-provider-api.js';
import { GMAIL_GOOGLE_API_HOST, gmailBackupSearchQuery } from '../../../core/const.js';
import { GmailParser, GmailRes } from './gmail-parser.js';
Expand Down Expand Up @@ -136,7 +136,10 @@ export class Gmail extends EmailProviderApi implements EmailProviderInterface {
};

public msgsGet = async (msgIds: string[], format: GmailResponseFormat): Promise<GmailRes.GmailMsg[]> => {
return await Promise.all(msgIds.map(id => this.msgGet(id, format)));
return await promiseAllWithLimit(
msgIds.map(id => () => this.msgGet(id, format)),
10
);
};

public labelsGet = async (): Promise<GmailRes.GmailLabels> => {
Expand Down
42 changes: 42 additions & 0 deletions extension/js/common/core/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -517,3 +517,45 @@ export const checkValidURL = (url: string): boolean => {
const pattern = /(http|https):\/\/([a-z0-9-]+((\.[a-z0-9-]+)+)?)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@\-\/]))?/;
return pattern.test(url);
};

// Type definition for a function that returns a promise
type PromiseFunction<T> = () => Promise<T>;

// promiseAllWithLimit as a const holding an arrow function
export const promiseAllWithLimit = <T>(promiseFunctions: PromiseFunction<T>[], limit: number): Promise<T[]> => {
return new Promise((resolve, reject) => {
let resolvedCount = 0;
let count = 0;
const results: T[] = new Array(promiseFunctions.length);
const len = promiseFunctions.length;

// Declare `next` as a const arrow function
const next = (promiseFunc: PromiseFunction<T>, index: number) => {
promiseFunc()
.then(result => {
results[index] = result;
resolvedCount++;
if (promiseFunctions.length) {
const nextPromiseFunc = promiseFunctions.shift();
if (nextPromiseFunc) {
next(nextPromiseFunc, count);
count++;
}
} else if (resolvedCount === len) {
resolve(results);
}
})
.catch(error => {
reject(error);
});
};

while (count < limit && promiseFunctions.length) {
const nextPromiseFunc = promiseFunctions.shift();
if (nextPromiseFunc) {
next(nextPromiseFunc, count);
count++;
}
}
});
};

0 comments on commit 88e99a0

Please sign in to comment.