Невозможно разрешить обещание в обратном вызове socket.io - PullRequest
1 голос
/ 08 июля 2019

Я создаю рекурсивную систему, которая пересылает пакет 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  

Журналы ненадежны, поэтому я попытался использовать точку останова, я все еще сначала иду в resol () (но я не могу его ввести), затем в reject (). Это похоже на подтверждение socket.io в другом потоке, но оно отлично работает, когда нет тайм-аута и сервер сразу отвечает

1 Ответ

0 голосов
/ 08 июля 2019

Обещание, которое передается recursiveSend, равно rejected по таймауту, после чего то же самое Обещание снова передается recursiveSend в улове, где вы пытаетесь resolve его.

Решение уже отклоненного обещания невозможно.

...