Sök…


Använda $ q.all för att hantera flera löften

Du kan använda $q.all funktionen för att anropa en .then efter att en rad löften har lyckats och hämtas de data som de löst med.

Exempel:

JS:

 $scope.data = []

 $q.all([
    $http.get("data.json"),
    $http.get("more-data.json"),
    ]).then(function(responses) {
      $scope.data = responses.map((resp) => resp.data);
    });

Ovanstående kod kör $http.get 2 gånger för data i lokala json-filer, när båda get metoden slutförd löser de sina tillhörande löften, när alla löften i matrisen är löst, så .then metoden med båda löften data inuti responses array argument.

Data mappas sedan så att de kan visas på mallen, vi kan sedan visa

HTML:

<ul>
   <li ng-repeat="d in data">
      <ul>
         <li ng-repeat="item in d">{{item.name}}: {{item.occupation}}</li>
      </ul>
   </li>
</ul>

JSON:

[{
  "name": "alice",
  "occupation": "manager"
}, {
  "name": "bob",
  "occupation": "developer"
}]

Använd $ q-konstruktören för att skapa löften

Konstruktorfunktionen $q används för att skapa löften från asynkrona API: er som använder återuppringningar för att returnera resultat.

$ q (funktion (lösa, avvisa) {...})

Konstruktorfunktionen får en funktion som åberopas med två argument, resolve och reject som är funktioner som används för att antingen lösa eller avvisa löfte.

Exempel 1:

function $timeout(fn, delay) {
    return = $q(function(resolve, reject) {
         setTimeout(function() {
              try {
                 let r = fn();
                 resolve(r);
              } 
              catch (e) {
                 reject(e);
              }
         }, delay);
     };
}
    

Exemplet ovan skapar ett löfte från WindowTimers.setTimeout API . AngularJS-ramverket ger en mer detaljerad version av denna funktion. För användning, se AngularJS $ timeout Service API Reference .

Exempel 2:

$scope.divide = function(a, b) {
    return $q(function(resolve, reject) {
      if (b===0) {
        return reject("Cannot devide by 0")
      } else {
        return resolve(a/b);
      }
    });
}

Ovanstående kod som visar en lovad delningsfunktion, den kommer att returnera ett löfte med resultatet eller avvisa med en anledning om beräkningen är omöjlig.

Du kan sedan ringa och använda .then

$scope.divide(7, 2).then(function(result) {
    // will return 3.5
}, function(err) {
    // will not run
})

$scope.divide(2, 0).then(function(result) {
    // will not run as the calculation will fail on a divide by 0
}, function(err) {
    // will return the error string.
})

Uppskjutande verksamhet med $ q.defer

Vi kan använda $q att skjuta upp operationer till framtiden medan vi har ett pågående löfteobjekt för närvarande, genom att använda $q.defer skapar vi ett löfte som antingen kommer att lösa eller avvisa i framtiden.

Den här metoden är inte likvärdigt med att använda $q konstruktören, eftersom vi använder $q.defer att lova en befintlig rutin som kanske eller kanske inte returnerar (eller någonsin hade returnerat) ett löfte alls.

Exempel:

var runAnimation = function(animation, duration) {
    var deferred = $q.defer();
    try {
        ...
        // run some animation for a given duration
        deferred.resolve("done");
    } catch (err) {
        // in case of error we would want to run the error hander of .then
        deferred.reject(err);
    }
    return deferred.promise;
}

// and then
runAnimation.then(function(status) {}, function(error) {})

  1. Se till att du alltid returnerar ett det deferred.promise objektet eller riskerar ett fel när du åberopar .then

  2. Se till att du alltid löser eller avvisar ditt uppskjutna objekt eller. .then kanske inte körs och att du riskerar att minnet läcker

Använda vinkellöften med $ q-tjänst

$q är en inbyggd tjänst som hjälper till att köra asynkronfunktioner och använda deras returvärden (eller undantag) när de är klara med bearbetningen.

$q är integrerad med $rootScope.Scope , vilket innebär snabbare spridning av upplösning eller avslag till dina modeller och undviker onödiga webbläsaråtervinningar, vilket skulle resultera i flimrande UI.

I vårt exempel kallar vi vår fabrik getMyData , som returnerar ett löfteobjekt. Om objektet är resolved returnerar det ett slumpmässigt nummer. Om det rejected returnerar det ett avslag med ett felmeddelande efter 2 sekunder.

I vinkelfabrik

function getMyData($timeout, $q) {
  return function() {
    // simulated async function
    var promise = $timeout(function() {
      if(Math.round(Math.random())) {
        return 'data received!'
      } else {
        return $q.reject('oh no an error! try again')
      }
    }, 2000);
    return promise;
  }
}

Använda löften vid samtal

angular.module('app', [])
.factory('getMyData', getMyData)
.run(function(getData) {
  var promise = getData()
    .then(function(string) {
      console.log(string)
    }, function(error) {
      console.error(error)
    })
    .finally(function() {
      console.log('Finished at:', new Date())
    })
})

För att använda löften, injicera $q som beroende. Här injicerade vi $q i getMyData fabriken.

var defer = $q.defer();

En ny instans av uppskjuten konstrueras genom att ringa $q.defer()

Ett uppskjutet objekt är helt enkelt ett objekt som avslöjar ett löfte såväl som de tillhörande metoderna för att lösa detta löfte. Den är konstruerad med $q.deferred() och visar tre huvudmetoder: resolve() , reject() och notify() .

  • resolve(value) - löser det härledda löfte med värdet.
  • reject(reason) - avvisar det härledda löfte med anledningen.
  • notify(value) - ger uppdateringar om status för löftets genomförande. Detta kan kallas flera gånger innan löften antingen löses eller avvisas.

Egenskaper

Det tillhörande löfteobjektet nås via löfteegenskapen. promise - {Löfte} - löfteobjekt associerat med denna uppskjutna.

En ny löfteinstans skapas när en uppskjuten instans skapas och kan hämtas genom att ringa deferred.promise .

Syftet med promise är att låta intresserade parter få tillgång till resultatet av den uppskjutna uppgiften när den är klar.

Löftsmetoder -

  • then(successCallback, [errorCallback], [notifyCallback]) - Oavsett när löftet var eller kommer att lösas eller avvisas, ring sedan en av framgångs- eller feluppringningarna asynkront så snart resultatet är tillgängligt. Återuppringningarna kallas med ett enda argument: resultatet eller avvisningsorsaken. Dessutom kan anmälan återuppringning kallas noll eller flera gånger för att ge en statusindikering, innan löften löses eller avvisas.

  • catch(errorCallback) - kortfattad för lover.then (null, errorCallback)

  • finally(callback, notifyCallback) - gör att du kan observera antingen uppfyllandet eller avslaget av ett löfte, men att göra det utan att ändra det slutliga värdet.

En av de mest kraftfulla funktionerna i löften är förmågan att kedja dem ihop. Detta gör att data flyter genom kedjan och manipuleras och muteras vid varje steg. Detta demonstreras med följande exempel:

Exempel 1:

// Creates a promise that when resolved, returns 4.
function getNumbers() {

  var promise = $timeout(function() {
    return 4;
  }, 1000);
  
  return promise;
}

// Resolve getNumbers() and chain subsequent then() calls to decrement
// initial number from 4 to 0 and then output a string.
getNumbers()
  .then(function(num) {
      // 4
      console.log(num);
      return --num;
  })
  .then(function (num) {
      // 3
      console.log(num);
      return --num;
  })
   .then(function (num) {
      // 2
      console.log(num);
      return --num;
  })
  .then(function (num) {
      // 1
      console.log(num);
      return --num;
  })
  .then(function (num) {
      // 0
      console.log(num);
      return 'And we are done!';
  })
  .then(function (text) {
      // "And we are done!"
      console.log(text);        
  });

Förpacka enkelt värde i ett löfte med $ q.when ()

Om allt du behöver är att förpacka värdet till ett löfte behöver du inte använda den långa syntaxen som här:

//OVERLY VERBOSE
var defer;
defer = $q.defer();
defer.resolve(['one', 'two']);
return defer.promise;

I det här fallet kan du bara skriva:

//BETTER
return $q.when(['one', 'two']);

$ q.when och dess alias $ q.resolve

Slår in ett objekt som kan vara ett värde eller ett (tredje part) då-löfte till ett löfte om $ q. Detta är användbart när du har att göra med ett objekt som kanske eller inte kan vara ett löfte, eller om löfte kommer från en källa som inte kan lita på.

- AngularJS $ q Service API Reference - $ q.when


Med utgåvan av AngularJS v1.4.1

Du kan också använda en ES6-konsekvent resolve

//ABSOLUTELY THE SAME AS when
return $q.resolve(['one', 'two'])

Undvik $ Q Uppskjuten antimönster

Undvik detta antimönster

var myDeferred = $q.defer();

$http(config).then(function(res) {  
   myDeferred.resolve(res);
}, function(error) {
   myDeferred.reject(error);
});

return myDeferred.promise;

Det finns inget behov av att tillverka ett löfte med $q.defer eftersom tjänsten $ http redan ger ett löfte.

//INSTEAD
return $http(config);

Ge bara det löfte som skapats av tjänsten $ http.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow