I'm creating a recursive system that resend socket.io packet till the server answer by fulfilling the socket.io acknowledgement. I create a promise that will reject in X seconds or resolve if the server answer in time, if it timeouts I recreate one with a longer timeout.
The problem is that the acknowledgement can't resolve the promise when there have been at least one timeout before and I don't understand why.
Here is a snippet of my code :
async emit(event, data) {
if (!this.socket) {
this.eventToSend[event] = data;
}
let timeoutRef;
let alreadyResolved = false;
return new Promise(async r => {
const sentPromise = timeout => {
return new Promise((resolve, reject) => {
console.log("------ New Call ------");
timeoutRef = setTimeout(() => {
if (alreadyResolved === true) {
console.log("Promise with timeout : " + timeoutRef + " is already resolved !!!");
} else {
console.log("promise " + timeoutRef + " timeouted !");
reject();
}
}, timeout);
console.log("Create promise with Timeout number : " + timeoutRef);
this.socket.emit(event, { data }, function(response) {
alreadyResolved = true;
console.log("try to delete " + timeoutRef + " timeout");
resolve(response);
});
});
};
try {
const result = await this.recursiveSend(sentPromise);
console.log("received the result " + result + ", aborting the process");
r(result);
} catch (e) {
console.error(e);
this.socket.disconnect(true);
}
});
}
async recursiveSend(promise, retryIndex = 0) {
try {
const result = await promise(this.timeoutRate[retryIndex]);
console.log("recevied result ! " + result);
return result;
} catch (e) {
// Here the setTimeout executed before I received the server acknowledgement
const newRetryIndex = retryIndex + 1;
if (newRetryIndex >= this.timeoutRate.length) {
throw new Error("Timeout exceeded, unable to join the socket");
} else {
return this.recursiveSend(promise, newRetryIndex);
}
}
}
This is the actual console log output :
...
------ New Call ------
Create promise with Timeout number : 32
promise 32 timeouted !
------ New Call ------
Create promise with Timeout number : 34
promise 34 timeouted !
------ New Call ------
Create promise with Timeout number : 36
try to delete 36 timeout // Here the promise is supposed to be resolved
Promise with timeout : 36 is already resolved !!! // But here we tried to reject it
Logs are not reliable so i tried using breakpoint, I still go in the resolve() first (but I can't enter it) then in the reject(). It's like the socket.io acknowledgement is made in another thread but it works perfectly when there is no timeout and the server respond right away