AngularJS
Angular beloftes met $ q service
Zoeken…
$ Q.all gebruiken om meerdere beloften af te handelen
U kunt de functie $q.all
gebruiken om een .then
methode aan te roepen nadat een reeks beloften is opgelost en de gegevens ophalen waarmee ze zijn opgelost.
Voorbeeld:
JS:
$scope.data = []
$q.all([
$http.get("data.json"),
$http.get("more-data.json"),
]).then(function(responses) {
$scope.data = responses.map((resp) => resp.data);
});
De bovenstaande code voert $http.get
2 keer uit voor gegevens in lokale json-bestanden, wanneer beide get
methode voltooid krijgen, lossen ze de bijbehorende beloften op, wanneer alle beloften in de array zijn opgelost, begint de .then
methode met beide beloftegegevens in de responses
array argument.
De gegevens worden vervolgens toegewezen, zodat deze op de sjabloon kunnen worden weergegeven, zodat we deze kunnen weergeven
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"
}]
De $ q-constructor gebruiken om beloften te maken
De constructorfunctie $q
wordt gebruikt om beloftes te maken van asynchrone API's die callbacks gebruiken om resultaten te retourneren.
$ q (functie (oplossen, weigeren) {...})
De constructorfunctie ontvangt een functie die wordt aangeroepen met twee argumenten, resolve
en reject
Dit zijn functies die worden gebruikt om de belofte op te lossen of af te wijzen.
Voorbeeld 1:
function $timeout(fn, delay) {
return = $q(function(resolve, reject) {
setTimeout(function() {
try {
let r = fn();
resolve(r);
}
catch (e) {
reject(e);
}
}, delay);
};
}
Het bovenstaande voorbeeld creëert een belofte van de WindowTimers.setTimeout API . Het AngularJS-framework biedt een meer uitgebreide versie van deze functie. Zie voor gebruik de AngularJS $ timeout Service API Reference .
Voorbeeld 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);
}
});
}
De bovenstaande code die een beloofde delingsfunctie toont, zal een belofte met het resultaat teruggeven of weigeren met een reden als de berekening onmogelijk is.
U kunt dan bellen en .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.
})
Bewerkingen uitstellen met $ q.defer
We kunnen $q
gebruiken om bewerkingen naar de toekomst uit te stellen terwijl we op dit moment een in afwachting van een belofte hebben, door $q.defer
, creëren we een belofte die in de toekomst zal oplossen of afwijzen.
Deze methode is niet hetzelfde als het gebruik van de $q
constructor, omdat we $q.defer
om een bestaande routine te beloven die al dan niet een belofte zal teruggeven (of ooit heeft teruggegeven).
Voorbeeld:
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) {})
Zorg ervoor dat u altijd een het
deferred.promise
object retourneert of een fout riskeert bij het aanroepen van.then
Zorg dat je altijd op te lossen of uw uitgesteld object te weigeren of
.then
kan niet draaien en loopt u het risico een geheugenlek
Hoekige beloften gebruiken met $ q-service
$q
is een ingebouwde service die helpt bij het uitvoeren van asynchrone functies en het gebruik van hun retourwaarden (of uitzondering) wanneer ze klaar zijn met verwerken.
$q
is geïntegreerd met het $rootScope.Scope
, wat betekent dat de resolutie of afwijzing sneller in uw modellen wordt $rootScope.Scope
en onnodige herschilderingen van de browser worden voorkomen, wat zou kunnen leiden tot een flitsende gebruikersinterface.
In ons voorbeeld noemen we onze fabriek getMyData
, die een getMyData
retourneert. Als het object is resolved
, wordt een willekeurig getal geretourneerd. Als het wordt rejected
, retourneert het na 2 seconden een afwijzing met een foutmelding.
In hoekige fabriek
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;
}
}
Beloftes gebruiken op afroep
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())
})
})
Om beloften te gebruiken, injecteer $q
als afhankelijkheid. Hier hebben we $q
geïnjecteerd in de fabriek van getMyData
.
var defer = $q.defer();
Een nieuw exemplaar van uitgesteld wordt samengesteld door $q.defer()
aan te roepen
Een uitgesteld object is gewoon een object dat een belofte blootstelt, evenals de bijbehorende methoden om die belofte op te lossen. Het is opgebouwd met behulp van de functie $q.deferred()
en geeft drie hoofdmethoden weer: $q.deferred()
resolve()
, reject()
en notify()
.
-
resolve(value)
- lost de afgeleide belofte op met de waarde. -
reject(reason)
- verwerpt de afgeleide belofte met de reden. -
notify(value)
- biedt updates over de status van de uitvoering van de belofte. Dit kan meerdere keren worden genoemd voordat de belofte wordt opgelost of afgewezen.
Eigendommen
Het bijbehorende belofteobject is toegankelijk via de belofte-eigenschap. promise
- {Belofte} - belofteobject gekoppeld aan dit uitgestelde.
Een nieuwe belofte-instantie wordt gemaakt wanneer een uitgestelde instantie wordt gemaakt en kan worden opgehaald door deferred.promise
aan te roepen.
Het doel van het promise
is om geïnteresseerde partijen toegang te geven tot het resultaat van de uitgestelde taak wanneer deze is voltooid.
Promise Methods -
then(successCallback, [errorCallback], [notifyCallback])
- Ongeacht wanneer de belofte werd of zal worden opgelost of afgewezen, roept vervolgens een van de succes- of foutcallback asynchroon aan zodra het resultaat beschikbaar is. De callbacks worden met een enkel argument aangeroepen: de reden voor het resultaat of de afwijzing. Bovendien kan de terugbelmelding voor melding nul of meer worden genoemd om een voortgangsindicatie te geven, voordat de belofte wordt opgelost of afgewezen.catch(errorCallback)
- steno voor belofte.then (null, errorCallback)finally(callback, notifyCallback)
- hiermee kunt u de vervulling of afwijzing van een belofte observeren, maar dit zonder de uiteindelijke waarde te wijzigen.
Een van de krachtigste kenmerken van beloften is de mogelijkheid om ze aan elkaar te koppelen. Hierdoor kunnen de gegevens door de keten stromen en bij elke stap worden gemanipuleerd en gemuteerd. Dit wordt aangetoond met het volgende voorbeeld:
Voorbeeld 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);
});
Zet eenvoudige waarde om in een belofte met $ q.when ()
Als je alleen maar de waarde in een belofte wilt omzetten, hoef je de lange syntaxis zoals hier niet te gebruiken:
//OVERLY VERBOSE
var defer;
defer = $q.defer();
defer.resolve(['one', 'two']);
return defer.promise;
In dit geval kunt u gewoon schrijven:
//BETTER
return $q.when(['one', 'two']);
$ q.when en zijn alias $ q.resolve
Wikkelt een object dat een waarde of een (derde partij) dan mogelijke belofte kan zijn in een $ q belofte. Dit is handig wanneer u te maken hebt met een object dat al dan niet een belofte is, of als de belofte afkomstig is van een bron die niet kan worden vertrouwd.
Met de release van AngularJS v1.4.1
U kunt ook gebruik maken van een ES6-consistente alias resolve
//ABSOLUTELY THE SAME AS when
return $q.resolve(['one', 'two'])
Vermijd het $ q uitgestelde antipatroon
Vermijd dit anti-patroon
var myDeferred = $q.defer(); $http(config).then(function(res) { myDeferred.resolve(res); }, function(error) { myDeferred.reject(error); }); return myDeferred.promise;
Het is niet nodig om een belofte te maken met $q.defer
omdat de $ http-service al een belofte retourneert.
//INSTEAD
return $http(config);
Retourneer eenvoudig de belofte gecreëerd door de $ http-service.