Catena Angolare $chiamate http correttamente?

Ho letto circa $q e promesse per giorni e giorni, e mi sembra di capire di si…un po’. Ho la seguente situazione in pratica:

  1. Un $richiesta http e controlla se una chiamata successiva può essere fatto.
  2. Se la prima chiamata ha esito negativo, il ritorno “no data”, se l’esito è positivo e dice una chiamata può essere effettuata, la seconda convocazione è fatta, se non – “no data” di nuovo. Se la seconda chiamata ha esito positivo, restituisce i dati, se non – “no data”. Sembra che questo (circa, ho semplificato per l’idea generale, quindi non preoccuparti per i piccoli errori qui):
            return $http.get (something)
                .then(function(allowedAccess){
                    if(allowedAccess){
                        return $http.get (somethingElse)
                            .then( function(result){return {data:result} },
                            function(error){return {data:"n0pe"} }
                        )
                    } else {
                        return {data:"n0pe"}
                    }
                },
                function(){ return {data:"n0pe"} });

Mi è stato detto di usare $q qui. Non so come o perché vorrei. Il $chiamate http, sono promesse già.

Se c’è un modo per rendere questa macchina, non la vedo. Appena ha finito di ri-leggere questo post sull’argomento. Essenzialmente, mi manca qualcosa /c’è un modo migliore per fare questo?

Edit: Anche appena ri-leggere un tutorial su concatenamento promesse – non gestire errori di chiamata a tutti. Fondamentalmente la pubblicazione di questo come di due diligence.

Edit 2: Questo è più di un elaborato sulla teoria sto chiedendo, estratto dall’articolo:

Questo è un esempio semplice però. Diventa davvero potente se il tuo allora() richiamata restituisce un’altra promessa. In tal caso, la prossima quindi() viene eseguito solo una volta che la promessa si risolve. Questo modello può essere utilizzato per una serie di richieste HTTP, per esempio (dove una richiesta dipende dal risultato della precedente):

Questo sembra essere parlando di catene come questo:

   asyncFn1(1)
    .then(function(data){return asyncFn2(data)})
    .then(function(data){return asyncFn3(data)})

Quindi, se ho capito bene questo). Non si applica a me, perché io non ho una 3 ° di funzione. b). Si potrebbe applicare a me, se ho avuto tre funzioni, perché mentre faccio un if all’interno del primo $richiesta http, e solo all’interno di se la dichiarazione faccio a tornare un’altra promessa. Quindi, teoricamente, se ho avuto tre async funzioni a catena, avrei bisogno di mettere la mia istruzione if all’interno di una promessa?

InformationsquelleAutor VSO | 2015-09-13

 

3 Replies
  1. 13

    Promette davvero aiutare con il codice di composizione di effettuare chiamate asincrone. In altre parole, essi consentono di comporre il codice in un modo simile a come si dovrebbe comporre un sincrono set di chiamate (con l’uso di incatenato .thens) e come se la sincronizzazione di codice in un try/catch blocco (con .catch).

    Così, immaginate che il vostro HTTP chiamate di blocco – la logica che si sarebbe cercare in questo modo:

    var allowedAccess, data;
    try {
      allowedAccess = $http.get(something);
    
      if (allowedAccess){
        try{
          var result = $http.get(somethingElse);
          data = {data: result};
        } catch (){
          data = {data: "n0pe"};
        }
      } else {
        data = {data: "n0pe"};
      }
    } catch (){
      data = {data: "n0pe"};
    }
    return data;

    Si potrebbe semplificare un po’:

    var allowedAccess, result;
    try {
      allowedAccess = $http.get(something);
      var result;
      if (allowedAccess) {
         result = $http.get(somethingElse);
      } else {
         throw;
      }
      data = {data: result};
    } catch () {
       data = {data: "n0pe"};
    }
    return data;

    E che si traduce in async versione:

    return $http
              .get(something)
              .then(function(allowedAccess){
                 if (allowedAccess){
                   return $http.get(somethingElse);
                 } else {
                   return $q.reject(); //this is the "throw;" from above
                 }
              })
              .then(function(result){
                 return {data: result};
              })
              .catch(function(){
                 return {data: "n0pe"};
              })

    Almeno, questo è il ragionamento si potrebbe applicare durante la composizione di codice, con rami e delle chiamate asincrone.

    Non sto dicendo che la versione che ho presentato è ottimale o a breve si è, tuttavia, più SECCA a causa di un errore di gestione. Ma basta rendersi conto che quando si fa .then(success, error) è equivalente a try/catch rispetto al precedente operazione asincrona – questo può o non può essere necessario, a seconda della specifica circostanza.

    • La ringrazio molto per la risposta dettagliata, ancora in elaborazione, tornerà ad accettare la vostra o Matt domani.
    • Cosa dobbiamo respingere con $q.rifiutare() qui? Io sono familiarità con l’utilizzo di rifiutare() su un differita creato con $q.rimandare(). Qui è solo rifiutando la seconda $http.chiamata? Ma non se la dichiarazione di non essere una promessa di un problema? Molto probabilmente mi sto perdendo qualcosa.
    • è equivalente a throw di sincronizzazione del mondo. E ‘ una respinta promessa, così va a finire nel .catch piuttosto che il prossimo .then
  2. 7

    Questo è come vorrei il codice di questo tipo di problema:

    //returns a promise that resolves some endpoint if allowed
    function getDataWithAccess(allowed){
        return allowed ? $http.get(someEndpoint) : $q.reject();
    }
    
    //do something with data
    function handleData(data){
        //do stuff with your data
    }
    
    //main chain
    $http.get(accessCredEndpoint)
        .then(getDataWithAccess)
        .then(handleData)
        .catch(function(err){
            return { data: "n0pe" };
        });

    Sì, questo è molto simile a New Dev risposta, però ho voluto fare un punto di estrazione di funzioni nei propri blocchi. Questo rende complessivamente il codice molto più leggibile.

    • Ti ringrazio per la risposta, a quanto pare ho bisogno di qualche tempo per digerire, tornerà ad accettare le Nuove o Dev risposta dopo un po ‘ di sonno.
  3. -2

    $q contribuirà a ridurre la piramide di chiamate come questo:

    async-call1.then(...
      aysnc-call2.then(...

    Questo post del blog – http://chariotsolutions.com/blog/post/angularjs-corner-using-promises-q-handle-asynchronous-calls/ – offre un modo pulito di fare più richieste HTTP. Notare il detergente utilizzando l’approccio di $q. Nel caso In cui si colpisce un singolo endpoint HTTP, usando il tuo metodo sarebbe stato proprio bene. Direi, quello che hai va bene anche; $q potrebbe consentire una maggiore flessibilità in futuro.

    Blog post descrive un servizio durante l’utilizzo di $q e il codice è più pulito.

    service('asyncService', function($http, $q) {
      return {
        loadDataFromUrls: function(urls) {
          var deferred = $q.defer();
          var urlCalls = [];
          angular.forEach(urls, function(url) {
            urlCalls.push($http.get(url.url));
          });
          //they may, in fact, all be done, but this
          //executes the callbacks in then, once they are
          //completely finished.
          $q.all(urlCalls)
          .then(...

    Io sono un principiante con promesse anche, in modo da prendere questo con un grano di sale.

    • L’OP è questione richiede, chiaramente, chiamate sequenziale, poiché una seconda chiamata dipende dal parametro di ritorno del primo. $q.all funziona quando le chiamate sono indipendenti tra loro
    • Buon punto, @NewDev. Grazie.

Lascia un commento