web-dev-qa-db-fra.com

L'utilisation de async dans setTimeout est-elle valide?

J'avais une fonction asynchrone en Javascript et j'y ai ajouté setTimeout. Le code ressemble à ça:

        let timer;
        clearTimeout(timer);
        timer =setTimeout(() => {
        (async() => {
            await this._doSomething();
        })();
        }, 2000);

SetTimeout a pour but d'ajouter 2 secondes avant l'exécution de la fonction. C'est pour être sûr que l'utilisateur a arrêté de taper.

Dois-je supprimer async/wait de cette fonction maintenant, puisque setTimeout est de toute façon asynchrone?

16
Marta

setTimeout ajoute un délai avant un appel de fonction, tandis que async/await est le sucre syntaxique au-dessus des promesses, un moyen d'enchaîner le code à exécuter après un appel se termine, donc ils ' re différent.

setTimeout a de terribles caractéristiques de gestion des erreurs, donc je recommande ce qui suit dans tout le code:

let wait = ms => new Promise(resolve => setTimeout(resolve, ms));

puis n'appelez plus jamais setTimeout directement.

Votre code devient maintenant:

let foo = async () => {
  await wait(2000);
  await this._doSomething();
}

sauf foo attend que doSomething se termine. C'est généralement souhaitable, mais sans contexte, il est difficile de savoir ce que vous voulez. Si vous vouliez exécuter doSomething en parallèle avec un autre code, je recommande:

async () => { await Promise.all([foo(), this._otherCode()]); };

pour rejoindre et capturer les erreurs au même endroit.

Si vous vouliez vraiment tirer et oublier _doSomething et ne pas l'attendre, vous pouvez perdre le await, mais vous devriez essayer/attraper les erreurs:

async () => {
  let spinoff = async () => { try { await foo(); } catch (e) { console.log(e); } };
  spinoff(); // no await!
}

Mais je ne recommande pas ce modèle, car il est subtil et peut être facile à manquer.

38
jib