javascript - Returnera ett tomt löfte


Jag har en funktion som returnerar ett jQuery-löfte. Det ser ut så här:

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

Jag gör detta så att jag kan återanvända denna funktion och kedja löfteåteruppringningar som:

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

Min fråga är, vad händer om jag vill bryta ut från addBooks tidigt och förhindra en resa till servern. Till exempel:

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'
    });
}

Mitt exempel kommer inte att kompilera eftersom mitt exempel med en kedjad done-callback förväntar sig att addBooks ska returnera ett promise-objekt, inte null. Hur kan jag returnera ett tomt promise (eller vilket korrekt objekt jag borde returnera i situationen)?

Svar #1

Hur kan jag returnera ett tomt löfte (eller vilket objekt som är korrekt att returnera i situationen)?

Ja, ett "tomt löfte" är lämpligt här, om du menar ett löfte som redan är uppfyllt med ingenting (undefined, null).

jQuery-syntaxen för att skapa sådant är att använda $.when med ett enda (eller inget) argument:

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

Svar #2

Du kan returnera ett upplöst löfte: Istället för

if (books <= 0) return null;

använda

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

Var försiktig, dock, eftersom jQuerys Promise-API gör något överraskande: Ibland anropar det din done/then/etc. callback synkront med done/then/etc.-anropet, ibland gör det inte det. De flesta promise-bibliotek säkerställer att anropet alltid är asynkront, även om du anropar done/then/etc. på ett upplöst promise. jQuery gör det inte, så du får subtila skillnader.

Till exempel, den här koden:

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

...kommer att logga

2
1

...om du gjorde ajax-anropet, men

1
2

...om du returnerade ett uppfyllt löfte.

Relaterade artiklar