2016-05-16 12 views
0

Ich bin ein neuer Entwickler und arbeite an einem ziemlich komplexen Szenario, wo, wenn der Benutzer spart, könnte es eine Sperre geben und der Benutzer hat die Chance, das Schloss zu überfahren. Wenn es eine Sperre gibt, da REST staatenlos ist, ist das Objekt, das ich auf dem PUT gesendet habe, verloren gegangen, so dass ich dem Benutzer erlauben muss, das Schloss zu überfahren und dann die Put-Anfrage erneut zu machen.verschachtelte Versprechen - besserer Weg?

In der zweiten if-Prüfung können Sie sehen, dass ich eine verschachtelte Versprechen habe. Von dem, was ich über Versprechungen und Rückrufe weiß, vereitelt dies den Zweck, Versprechungen zu verwenden. Ich las einige andere Antworten durch, verstand aber nicht das Konzept, ein Versprechen im inneren/verschachtelten Versprechen zurückzugeben. Wie kann ich den unten stehenden Code umgestalten, damit er mehr mit Best Practices übereinstimmt und keine Versprechen einnistet?

//the user chooses to over ride someone else's lock 
    $scope.$on('forceLockAfterModalSubmit', function (e, data) { 
    if (!$scope.newItemCreatedIsLocked) { 
     $scope.setLockForCurrentUser(); 
     $scope.editMode = true; 
    } 
    if ($scope.newItemCreatedIsLocked) { 
     service.forceLock($scope.id).then(function() { 
     itemService.updateItem($scope.itemForRequestBeforeLockResponse).then(function() { 
      $scope.postPUTRequestActions($scope.itemForRequestBeforeLockResponse); 
     }) 
     }, function (err) { 
     console.log(err); 
     }) 
    } 
    }) 
+2

mögliches Duplikat von [Entfernen verschachtelter Versprechen] (http://stackoverflow.com/a/22000931/1048572) – Bergi

Antwort

2

Sie mischen Rückrufe und Versprechen und machen es schwieriger, als es sein muss. Alle asynchronen Funktionen sollten eine Zusage zurückgeben, und anstatt die zweite als Fehlerbehandlung zu verwenden, sollten Sie eine .catch()-Funktion behandeln die Fehler.

Der Code, den Sie im Moment haben könnte durch

$scope.$on('forceLockAfterModalSubmit', function(e, data) { 
    if (!$scope.newItemCreatedIsLocked) { 
    $scope.setLockForCurrentUser(); 
    $scope.editMode = true; 
    } 
    if ($scope.newItemCreatedIsLocked) { 
    service.forceLock($scope.id) 
     .then(function() { 
     return itemService.updateItem($scope.itemForRequestBeforeLockResponse); 
     }) 
     .then(function() { 
     return $scope.postPUTRequestActions($scope.itemForRequestBeforeLockResponse); 
     }) 
     .catch(function(err) { 
     console.log(err); 
     }); 
    } 
}); 

Wenn Sie eine saubere Lösung wollen ersetzt werden, eine Funktion erklären könnte, dass Ihr itemService.updateItem und $scope.postPUTRequestActions mit dem scoped id ruft und Sie würden am Ende mit

$scope.$on('forceLockAfterModalSubmit', function(e, data) { 
    if (!$scope.newItemCreatedIsLocked) { 
    $scope.setLockForCurrentUser(); 
    $scope.editMode = true; 
    } 
    if ($scope.newItemCreatedIsLocked) { 
    service.forceLock($scope.id) 
     .then(itemService.updateItem) 
     .then($scope.postPUTRequestActions) 
     .catch(function(err) { 
     console.log(err); 
     }); 
    } 
}); 

das ist sowohl einfach zu verstehen und zu folgen.

+0

"* Sie sollten mit jedem Fehler in einem' .catch() '*" - nicht unbedingt, gibt es sehr gute Gründe, das zweite Then-Argument zu verwenden, da man manchmal [etwas anderes] benötigt (http://stackoverflow.com/q/24662289/1048572). Aber Sie haben Recht, ein generischer Fehlerhandler sollte immer am Ende der Kette in einen 'catch' gehen. – Bergi

+0

@Bergi, guter Punkt und Beispiel, obwohl in diesem Fall das zweite Argument nur als Fehlerbehandlung verwendet wird, die ich ansprechen wollte. Ich habe meine Antwort aktualisiert! –

+0

danke. leider benutze ich jquery versprechen in meinem projekt so catch wird nicht funktionieren :) – devdropper87

-1

Auch ziemlich neu, aber vielleicht könnte dies nützlich sein. Eine andere Idee ist, dass in der ersten Funktion, die eine Verheißung zurückgibt, Sie die andere Funktion aufrufen und setTimeout (function2, "Millisekunden hier einfügen") verwenden möchten, obwohl das die Dinge auf lange Sicht verlangsamen kann, da Sie es wollen sobald die Daten fertig sind ... Scheint Hacky für mich, aber es könnte kurzfristig eine Bandage sein.

Auf eine etwas verwandte Anmerkung möchten Sie vielleicht Dinge so schreiben, um mit der Lesbarkeit zu helfen.

service.then(successFunction).catch(errorFunction); 
 

 
function successFunction(response) { 
 
    if (response == "Valid Data") { 
 
     return response; 
 
    } else { 
 
     console.log("Something is wrong with the success function!"); 
 
     return response; 
 
    } 
 

 
    functon errorFunction(response) { 
 
     console.log("Error occurred in the service!"); 
 
    }

hoffe, das hilft einige was.

Verwandte Themen