Quale di questi metodi di promessa è considerato una best practice?

0

Ho un paio di metodi asincroni che sono fondamentalmente un sì e nessuna risposta isUsernameAvalible() isOnline() isImage() yada yada... probabilmente avrai ormai il punto.

Come dimostrazione ... prova a pensare a questo come a una promessa di async più generica (non che abbia nulla a che fare con la manipolazione delle immagini) e potrebbe funzionare allo stesso modo per esempio isOnline(id).then(showOn, showOff)

function isImage (file) {
    return new Promise(resolve => {
        let img = new Image
        img.src = URL.createObjectURL(file)
        img.onload = () => resolve(true)
        img.onerror = () => resolve(false)
    })
}


function showError () {
    // alert(not an image)
}

input.onchange = evt => {
    isImage(evt.target.files[0]).then(isImage => {
        isImage ? convert() : showError()
    }, err => {
        // code execution failed
        // couldn't tell if it's a image or not
        // 
        // alert(unknown error)
        // URL.createObjectURL is not a function
    })
}

vs

function isImage (file) {
    return new Promise((resolve, reject) => {
        let img = new Image
        img.src = URL.createObjectURL(file)
        img.onload = () => resolve(true)
        img.onerror = () => reject(new Error('Not a image file'))
    })
}

function showError (error) {
    // alert(instanceof error)
}

input.onchange = evt => {
    // This becomse a bit more nicer to read and write
    isImage(evt.target.files[0]).then(convert, showError)
}

Mi sento come se il secondo metodo fosse un modo migliore per affrontarlo. Ma uso improprio il modo in cui le promesse dovrebbero gestire gli errori

Mi sento come se isSomething() dovesse risolversi in un valore booleano vero / falso e rifiutato se c'è qualche errore di esecuzione del codice. Come non essere in grado di fare una richiesta GET

Che ne pensi?

    
posta Endless 24.03.2016 - 10:20
fonte

3 risposte

3

Sì, è sorprendente e / o fuorviante per isImage rifiutare piuttosto che risolvere a false quando il percorso file risolve correttamente una non immagine. Ma il "codice client" è effettivamente più breve e più semplice nel secondo esempio.

Ciò che questo mi dice è che il tuo esempio "codice cliente" vuole un'API diversa da quella implicita dal nome isImage . Suggerirei un metodo di ritorno promettente diverso chiamato getImage che presuppone ciecamente che il percorso file porti a un'immagine (e quindi la sua promessa dovrebbe essere rifiutata su non immagini).

    
risposta data 24.03.2016 - 10:37
fonte
0

Poiché ci sono solo due stati e in genere si desidera seguire percorsi di codice completamente diversi in caso di successo ed errore, sembra più utile e pulito a reject() se l'immagine non viene caricata. Noterai che il tuo gestore .then() sembra più semplice perché i casi di successo e di errore sono già suddivisi per te.

Molto di decidere quale dovrebbe essere un valore di ritorno in adempimento rispetto a un errore di rifiuto dipende interamente da te.

Il mio rasoio principale per decidere è "quale codice di chiamata normalmente codificherà?". Se il codice chiamante di solito desidera continuare l'elaborazione di altre operazioni asincrone sequenziali, resolve(xxx) ha senso poiché ciò consente a una catena .then() di continuare ad andare. Se è improbabile che il risultato continui a elaborare .then() a causa dell'errore, allora reject(yyyy) sembra più utile e appropriato.

Se sono i isImage() di nomi che ti infastidiscono e ti fanno pensare che entrambi i casi dovrebbero risolversi in booleano, puoi cambiarlo in qualcosa come validateImage() o checkImage() o verifyImage() .

Ottenere un errore di caricamento è in genere un errore significativo nel grande schema delle cose. Ad esempio, un 404 da una chiamata ajax sarebbe sempre considerato un errore. Perché non qualcosa di simile per un'immagine che non verrà caricata.

    
risposta data 24.03.2016 - 10:38
fonte
0

it is surprising and/or misleading for isImage to reject rather than resolve to false when the filepath successfully resolves to a non-image

Sono d'accordo, il mio buon senso dice che dovrebbe rifiutare solo se c'è stato qualche errore
Chi si attiene alla risoluzione di true o false (metodo 1)
Avevo anche in mente come dovrebbe funzionare se usato rendimento / attesa. (non vorrebbe racchiuderlo in un try / catch)

Quindi sto facendo la funzione di ordine superiore invece di tenerlo leggermente più leggibile

// function that returns a function and calls a function
function yepNope(yep, no){
   return trutly => trutly ? yep() : no()
}

isImage(file).then( yepNope(convert, wrongFormat), execError )
isOnline(userId).then( yepNope(showOn, showOff), networkError )
    
risposta data 24.03.2016 - 12:16
fonte

Leggi altre domande sui tag