2014-06-06 8 views
8

Ich bin neu in der Welt der Versprechen und ich bin mir nicht sicher, ob ich vollständig verstehe, wie man sie in einigen Fällen verwendet.Stoppen Sie die Ausführung eines Versprechens Sequelize in Express.js

Sequelize kürzlich hinzugefügt Unterstützung verspricht, die wirklich macht meinen Code lesbarer. Ein typisches Szenario besteht darin, Fehler in unendlichen Rückrufen mehrmals zu vermeiden. Der Code unten gibt immer 204 zurück, während ich möchte, dass 404 zurückgegeben wird, wenn das Foto nicht gefunden werden kann.

Gibt es eine Möglichkeit, Sequelize anzuweisen, die Ausführung der Versprechenskette nach dem Senden von 404 "anzuhalten"? Beachten Sie, dass res.send asynchron ist, sodass die Ausführung nicht gestoppt wird.

// Find the original photo 
Photo.find(req.params.id).then(function (photo) { 
    if (photo) { 
     // Delete the photo in the db 
     return photo.destroy(); 
    } else { 
     res.send(404); 
     // HOW TO STOP PROMISE CHAIN HERE? 
    } 
}).then(function() { 
    res.send(204); 
}).catch(function (error) { 
    res.send(500, error); 
}); 

Natürlich ist dieses Beispiel trivial und könnte leicht mit Rückrufen geschrieben werden. Aber in den meisten Fällen kann der Code viel länger werden.

+0

Was Sie brauchen, ist ein Weg, um das Versprechen zu markieren, wie an dieser Stelle aufgelöst . Ich bin nicht vertraut mit Sequelize, aber ich nehme an, dass es einen Weg geben muss, das zu tun. –

+0

Danke Edwin. Das einzige, was ich weiß ist, dass Sequelize Bluebird verwendet. Ich sehe jedoch nichts in ihrer API, das es mir erlaubt, eine Versprechungskette zu stoppen. – Pedro

+1

Wenn Sie innerhalb Ihres 'then' Handlers" werfen ", wird die Kette zurückgewiesen. Es gibt auch ein (offenes Problem) [https://github.com/sequelize/sequelize/issues/272], um den Suchaufruf automatisch abzulehnen, wenn kein Ergebnis gefunden wird. Sie können Ihre Unterstützung dort äußern, wenn Sie die Funktion benötigen –

Antwort

6

Ihre Versprechensketten müssen nicht unbedingt linear sein. Sie können "abzweigen" und eine separate Versprechungskette für den Erfolgsfall anlegen, indem Sie beliebig viele verketten, während Sie für den Fehlerfall eine separate (kürzere) Versprechungskette haben.

Konzeptionell sieht das wie folgt aus:

  Photo.find 
     / \ 
     /  \ 
    (success) (failure) 
    /   \ 
    /   \ 
photo.destroy res.send(404) 
    | 
    | 
res.send(204) 

Und in dem eigentlichen Code, die wie folgt aussehen:

// Find the original photo 
Photo.find(req.params.id).then(function (photo) { 
    if (photo) { 
     // Delete the photo in the db 
     return photo.destroy().then(function() { 
      res.send(204); 
     }); 
    } else { 
     res.send(404); 
    } 
}).catch(function (error) { 
    res.send(500, error); 
}); 
+0

Ja, das ist ziemlich viel, was ich getan habe. Ich habe erwartet, dass Sequelize einfach mein 'find()' Versprechen ablehnt, um zu viel verschachtelten Code zu vermeiden. Letzte Frage: Weißt du, ob ich noch eine 'catch()' für das 'destroy()' Versprechen hinzufügen muss? Oder wird es am Ende durch den Fang gehandhabt? Vielen Dank! – Pedro

+0

@PedroCheckos, es sei denn, Sie definieren einen separaten 'catch()' Block innerhalb Ihrer 'Photo.destroy()' Versprechungskette, sollten alle unbehandelten Ausnahmen zum äußeren 'catch()' Block "aufgebläht" werden. –

+0

Ehrfürchtig, das ist alles was ich wissen musste! Vielen Dank für die Tipps :) – Pedro

Verwandte Themen