无法在socket.io回调中解析Promise

时间:2019-07-08 10:19:23

标签: javascript node.js promise socket.io settimeout

我正在创建一个递归系统,该系统将重新发送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确认一样,但是在没有超时并且服务器立即响应的情况下,它可以完美地工作

1 个答案:

答案 0 :(得分:0)

传递给recursiveSend的Promise在超时时为rejected,然后在捕获中再次将相同的Promise传递给recursiveSend,在这里您尝试{{1 }}。

无法解决已经被拒绝的Promise。