AngularJS
Des promesses angulaires avec le service $ q
Recherche…
Utiliser $ q.all pour gérer plusieurs promesses
Vous pouvez utiliser la fonction $q.all
pour appeler une méthode .then
après avoir .then
un tableau de promesses et récupérer les données avec .then
elles ont été résolues.
Exemple:
JS:
$scope.data = []
$q.all([
$http.get("data.json"),
$http.get("more-data.json"),
]).then(function(responses) {
$scope.data = responses.map((resp) => resp.data);
});
Le code ci - dessus fonctionne $http.get
2 fois pour les données dans les fichiers JSON locaux, lorsque les deux get
la méthode complète , ils résolvent leurs promesses associées, lorsque toutes les promesses du tableau sont résolus, la .then
méthode commence par les données de promesses à l' intérieur des responses
argument de tableau.
Les données sont ensuite mappées pour pouvoir être affichées sur le modèle, nous pouvons alors afficher
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"
}]
Utiliser le constructeur $ q pour créer des promesses
La fonction constructeur $q
permet de créer des promesses à partir d’API asynchrones qui utilisent des rappels pour renvoyer des résultats.
$ q (fonction (résoudre, rejeter) {...})
La fonction constructeur reçoit une fonction appelée avec deux arguments, resolve
et reject
qui sont des fonctions utilisées pour résoudre ou rejeter la promesse.
Exemple 1:
function $timeout(fn, delay) {
return = $q(function(resolve, reject) {
setTimeout(function() {
try {
let r = fn();
resolve(r);
}
catch (e) {
reject(e);
}
}, delay);
};
}
L'exemple ci-dessus crée une promesse à partir de l' API WindowTimers.setTimeout . Le framework AngularJS fournit une version plus élaborée de cette fonction. Pour en savoir plus, consultez la référence de l'API AngularJS $ timeout Service .
Exemple 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);
}
});
}
Le code ci-dessus montrant une fonction de division promis, il renverra une promesse avec le résultat ou rejetera avec une raison si le calcul est impossible.
Vous pouvez alors appeler et utiliser .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.
})
Report des opérations en utilisant $ q.defer
Nous pouvons utiliser $q
pour différer les opérations à venir tout en ayant un objet prometteur en attente, en utilisant $q.defer
nous créons une promesse qui sera résolue ou rejetée dans le futur.
Cette méthode n'est pas équivalente à l'utilisation du constructeur $q
, car nous utilisons $q.defer
pour promouvoir une routine existante qui peut ou peut ne pas renvoyer une promesse.
Exemple:
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) {})
Assurez-vous de toujours renvoyer l'objet
deferred.promise
ou risquez une erreur lors de l'appel de.then
Assurez-vous de toujours résoudre ou rejeter votre objet différé ou
.then
peut ne pas fonctionner et vous risquez une fuite de mémoire
Utiliser des promesses angulaires avec le service $ q
$q
est un service intégré qui aide à exécuter des fonctions asynchrones et à utiliser leurs valeurs de retour (ou exceptions) une fois le traitement terminé.
$q
est intégré au mécanisme d'observation du modèle $rootScope.Scope
, ce qui signifie une propagation plus rapide de la résolution ou du rejet dans vos modèles et évite $rootScope.Scope
inutilement le navigateur, ce qui entraînerait une scintillement de l'interface utilisateur.
Dans notre exemple, nous appelons notre usine getMyData
, qui renvoie un objet promis. Si l'objet est resolved
, il renvoie un nombre aléatoire. S'il est rejected
, il renvoie un rejet avec un message d'erreur après 2 secondes.
Dans l'usine angulaire
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;
}
}
Utiliser des promesses sur appel
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())
})
})
Pour utiliser des promesses, injectez $q
comme dépendance. Ici, nous avons injecté $q
dans la fabrique getMyData
.
var defer = $q.defer();
Une nouvelle instance de différé est construite en appelant $q.defer()
Un objet différé est simplement un objet qui expose une promesse ainsi que les méthodes associées pour résoudre cette promesse. Il est construit en utilisant la fonction $q.deferred()
et expose trois méthodes principales: resolve()
, reject()
et notify()
.
-
resolve(value)
- Résout la promesse dérivée avec la valeur. -
reject(reason)
- rejette la promesse dérivée avec la raison. -
notify(value)
- fournit des mises à jour sur l'état de l'exécution de la promesse. Cela peut être appelé plusieurs fois avant que la promesse soit résolue ou rejetée.
Propriétés
L'objet promis associé est accessible via la propriété promis. promise
- {Promise} - objet de promesse associé à ce différé.
Une nouvelle instance de promesse est créée lorsqu'une instance différée est créée et peut être récupérée en appelant deferred.promise
.
L'objet de la promise
est de permettre aux parties intéressées d'accéder au résultat de la tâche différée une fois terminé.
Méthodes de promesses -
then(successCallback, [errorCallback], [notifyCallback])
- Indépendamment du moment où la promesse était ou sera résolue ou rejetée, appelle l'un des rappels de succès ou d'erreur de manière asynchrone dès que le résultat est disponible. Les callbacks sont appelés avec un seul argument: le résultat ou la raison du rejet. De plus, le rappel de notification peut être appelé zéro ou plusieurs fois pour fournir une indication de progression, avant que la promesse ne soit résolue ou rejetée.catch(errorCallback)
- raccourci pour promise.then (null, errorCallback)finally(callback, notifyCallback)
- vous permet d'observer l'accomplissement ou le rejet d'une promesse, mais de le faire sans modifier la valeur finale.
L'une des caractéristiques les plus puissantes des promesses est la capacité de les enchaîner. Cela permet aux données de circuler dans la chaîne et d'être manipulées et mutées à chaque étape. Ceci est démontré avec l'exemple suivant:
Exemple 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);
});
Enveloppez la valeur simple dans une promesse en utilisant $ q.when ()
Si tout ce dont vous avez besoin est d'encapsuler la valeur dans une promesse, vous n'avez pas besoin d'utiliser la syntaxe longue comme ici:
//OVERLY VERBOSE
var defer;
defer = $q.defer();
defer.resolve(['one', 'two']);
return defer.promise;
Dans ce cas, vous pouvez simplement écrire:
//BETTER
return $q.when(['one', 'two']);
$ q.when et son alias $ q.resolve
Entoure un objet qui pourrait être une valeur ou une promesse (tierce) alors capable dans une promesse $ q. Ceci est utile lorsque vous traitez avec un objet qui peut ou peut ne pas être une promesse, ou si la promesse provient d'une source qui ne peut pas être fiable.
Avec la sortie d'AngularJS v1.4.1
Vous pouvez également utiliser un alias cohérent ES6 resolve
//ABSOLUTELY THE SAME AS when
return $q.resolve(['one', 'two'])
Évitez les $ q Anti-Pattern différé
Éviter ce anti-pattern
var myDeferred = $q.defer(); $http(config).then(function(res) { myDeferred.resolve(res); }, function(error) { myDeferred.reject(error); }); return myDeferred.promise;
Il n'est pas nécessaire de fabriquer une promesse avec $q.defer
car le service $ http renvoie déjà une promesse.
//INSTEAD
return $http(config);
Renvoyez simplement la promesse créée par le service $ http.