JavaScript - Promises - How can we return a promise if we need to use setTimeout?

javascript-promises

// JavaScript - Promises - How can we return a promise if we need to use setTimeout?

I was working with Salesforce.  I had a report with more than 50000 contacts.  If I 
just run the report using the runReport method, it throws an exception.  To get around
this limitation, I have to use the runAsyncReport method, which returns an instanceId, 
and then I have to repeatedly check the status of this report using the given instanceId.

My code:

public startRecordCount(id: string, useAlternateEmail: boolean): Promise<ReportInstance> {
    let self = this;

    return new Promise<ReportInstance>(
        function (resolve, reject) {
            self.sfUtil.invokeRemote({
                endPoint: self.appConfig.endPoints.startRecordCount,
                success: function (result) {
                    return resolve(result);
                },
                error: function (result, event) {
                    console.log(result);
                    console.log(event);
                    return reject({ 'result': result, 'event': event });
                },
                arguments: [
                    id, useAlternateEmail
                ]
            });
        }
    );
}
public getReportInstance(id: string): Promise<ReportInstance> {
    let self = this;

    return new Promise<ReportInstance>(
        function (resolve, reject) {
            self.sfUtil.invokeRemote({
                endPoint: self.appConfig.endPoints.getReportInstance,
                success: function (result) {
                    return resolve(result);
                },
                error: function (result, event) {
                    console.log(result);
                    console.log(event);
                    return reject({ 'result': result, 'event': event });
                },
                arguments: [
                    id
                ]
            });
        }
    );
}

private getReportAsyncFinalLoop(instanceId: string, success: Function, failure: Function) {
    let self = this;
    self.getReportInstance(instanceId)
    .then(reportInstance => {
        if (reportInstance.status == 'Success') {
            return success(reportInstance);
        } else {
            setTimeout(function () {
                self.getReportAsyncFinalLoop(instanceId, success, failure);
            }, 1000);
        }
    });
}

public getReportAsyncFinal(instanceId: string): Promise<ReportInstance> {
    let self = this;
    return new Promise<ReportInstance>(
        function (resolve, reject) {
            self.getReportAsyncFinalLoop(instanceId, resolve, reject);
        }
    );
}

In the above code, I want to use setTimeout, because without using setTimeout, 
my code may hit the remote end-point too fast, and may run into API limit, or may 
cause browser to display error.  In the above code, I achieved this using two 
functions (getReportAsyncFinalLoop and getReportAsyncFinal), but I want to 
achieve this with just one function.  I can probably do this by wrapping the 
setTimeout inside a promise:

public getReportAsyncFinal(instanceId: string): Promise<ReportInstance> {
    let self = this;
    return new Promise<ReportInstance>(
        function (resolve, reject) {
            let self = this;
            self.getReportInstance(instanceId)
            .then(reportInstance => {
                if (reportInstance.status == 'Success') {
                    resolve(reportInstance);
                } else {
                    return new Promise<ReportInstance>(
                        function(res, rej) {
                            setTimeout(function() {
                                self.getReportAsyncFinal(instanceId);
                            }, 1000);
                        }
                    )
                }
            })
        }
    );
}
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License