我正在创建一个递归系统,该系统将重新发送socket.io数据包,直到服务器通过完成socket.io确认来应答为止。我创建了一个承诺,该承诺将在X秒内拒绝,或者解决服务器是否及时答复的问题(如果超时),我将重新创建超时时间更长的请求。
问题在于,如果至少有一个超时时间,并且我不知道为什么,那么确认无法解决承诺。
这是我的代码的片段:
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);
}
}
}
这是实际的控制台日志输出:
...
------ 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
日志不可靠,所以我尝试使用断点,但我仍然先进入resolve()(但我无法输入它),然后进入拒绝()。就像在另一个线程中进行socket.io确认一样,但是在没有超时并且服务器立即响应的情况下,它可以完美地工作
答案 0 :(得分:0)
传递给recursiveSend
的Promise在超时时为rejected
,然后在捕获中再次将相同的Promise传递给recursiveSend
,在这里您尝试{{1 }}。
无法解决已经被拒绝的Promise。