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);
}
)
}
})
}
);
}





