web-dev-qa-db-fra.com

Retourne une promesse vide

J'ai une fonction qui renvoie une promesse jQuery. Cela ressemble à ceci:

addBooks(books: Array<Books>) {
    return $.ajax({
        url: '/Books/AddBooks/',
        type: 'POST',
        data: ko.toJSON(books),
        contentType: 'application/json'
    });
}

Je fais cela pour pouvoir réutiliser cette fonction et chaîner des rappels de promesses comme:

addBooks.done(() => { alert("Books added!"); })

Ma question est de savoir si je veux sortir d’addBooks plus tôt et empêcher un voyage sur le serveur. Par exemple:

addBooks(books: Array<Books>) {

    // An empty array was passed in for some reason.
    // Theres nothing to add so dont try to POST
    if (books <= 0) return null;

    return $.ajax({
        url: '/Books/AddBooks/',
        type: 'POST',
        data: ko.toJSON(books),
        contentType: 'application/json'
    });
}

Mon exemple ne se compilera pas car mon exemple de rappel terminé enchaîné s'attend à ce que addBooks retourne un objet promis, et non null. Comment puis-je retourner une promesse vide (ou quel que soit l'objet correct que je devrais retourner dans la situation)?

20
Jonathan Eckman

Comment puis-je retourner une promesse vide (ou quel que soit l'objet correct que je devrais retourner dans la situation)?

Oui, une "promesse vide" est appropriée ici, si vous voulez dire une promesse qui est déjà remplie sans rien (undefined, null).

La syntaxe jQuery pour créer un tel utilise $.when avec un seul (ou aucun) argument:

if (books <= 0) return $.when(null);
25
Bergi

Vous pouvez retourner une promesse résol: au lieu de

if (books <= 0) return null;

utilisation

if (books <= 0) return $.Deferred().resolve();

Attention, cependant, que l'API Promise de jQuery fait quelque chose de surprenant: Parfois, elle appelle votre done/then/etc. rappel de façon synchrone avec done/then/etc. appeler, parfois non. La plupart des bibliothèques promises garantissent que l'appel est toujours asynchrone, même si vous appelez done/then/etc. sur une promesse résolue. jQuery ne le fait pas, vous obtenez donc des différences subtiles.

Par exemple, ce code:

addBooks(() => console.log(1));
console.log(2);

... se connectera

 2 
 1 

... si vous avez fait l'appel ajax, mais

 1 
 2 

... si vous avez renvoyé une promesse résolue.

8
T.J. Crowder

De https://api.jquery.com/jquery.when/

Si vous ne lui passez aucun argument, jQuery.when() renverra une promesse résolue.

par exemple.

if (books <= 0) return $.when();

et, si vous avez besoin d'une valeur qui n'est pas indéfinie transmise:

Si un seul argument est passé à jQuery.when () et que ce n'est pas un différé ou une promesse , il sera traité comme un différé résolu et tout doneCallback attaché sera exécuté immédiatement. Les doneCallbacks passent l'argument d'origine.

par exemple. un tableau vide est transmis:

if (books <= 0) return $.when([]);

par exemple. un objet vide est transmis:

if (books <= 0) return $.when({});
3
Gone Coding