Je dois utiliser (de grandes quantités) de code existant dans un environnement Angular 2. Ce code utilise beaucoup de $timeout
service d’AngularJS 1.x. Contrairement à divers autres services AngularJS 1.x utilisés dans le code, j'ai du mal à trouver des informations sur un Angular 2 équivalent pour le $timeout
un service.
Les documents angulaires ne semblent pas contenir de mention d'un service avec timeout
- quelque chose dans son nom. L'article Mise à niveau de AngularJS ) == mentionne le scénario auquel je suis confronté:
Peut-être souhaitez-vous accéder aux services intégrés d’AngularJS tels que
$location
ou$timeout
.
Malheureusement, l'article n'explique pas réellement comment accéder à ces services particuliers, car l'exemple suivant HeroesService
suppose un service sans aucune dépendance fournie par AngularJS 1.x.
Des articles tels que celui-ci suggèrent d'utiliser la fonction native setTimeout
fonction ne correspond pas aux capacités du $timeout
services, soit.
Comment puis-je reproduire le $timeout
Fonctionnalités dans l’environnement Angular 2??
EDIT: Comme il a été noté dans les réponses, les inconvénients de la fonction native setTimeout
ne sont pas pertinents lors de l’utilisation de Angular 2. Dans ce cas, si j’avais la totalité de $q
de AngularJS 1.x, je pourrais reproduire le $timeout
fonctionne à peu près comme ceci:
function $timeout(fn, delay) {
var result = $q.defer();
setTimeout(function () {
$q.when(fn()).then(function (v) {
result.resolve(v);
});
}, delay);
return result.promise;
}
Utilisez la fonction native setTimeout
. Il n’est plus nécessaire d’utiliser des services spéciaux dans Angular. Cela est dû à l’introduction de zones , plus précisément NgZone .
Des articles tels que celui-ci suggèrent que l'utilisation de la fonction native setTimeout ne soit pas à la hauteur des capacités des services $ timeout.
Pourquoi vous le dites? La tâche principale de $timeout
Le service devait commencer à résumer après l’exécution de la fonction retardée. Vous pouvez le voir depuis les sources:
function $TimeoutProvider() {
this.$get = ['$rootScope', '$browser', '$q', '$$q', '$exceptionHandler',
function($rootScope, $browser, $q, $$q, $exceptionHandler) {
timeoutId = $browser.defer(function() {
try {
deferred.resolve(fn.apply(null, args));
} catch (e) {
...
if (!skipApply) $rootScope.$apply(); <-------------------- here
}, delay);
Dans Angular zone.js
intercepte toutes les opérations asynchrones et lance la détection des modifications dans Angular qui est sorte de version améliorée de digest .
Si vous devez répliquer le $timeout
, vous pouvez approximativement le faire comme ceci:
function $timeout(fn, delay, ...args) {
let timeoutId;
$timeout.cancel = $timeout.cancel || function (promise) {
if (promise && promise.$$timeoutId in $timeout.promises) {
$timeout.promises[promise.$$timeoutId][1]('canceled');
delete $timeout.promises[promise.$$timeoutId];
return clearTimeout(promise.$$timeoutId);
}
return false;
};
$timeout.promises = $timeout.promises || {};
const promise = new Promise((resolve, reject) => {
timeoutId = setTimeout(function () {
try {
resolve(fn.apply(null, args));
} catch (e) {
reject(e);
} finally {
delete $timeout.promises[promise.$$timeoutId];
}
}, delay);
$timeout.promises[timeoutId] = [resolve, reject];
});
promise.$$timeoutId = timeoutId;
return promise;
}
// some basic testing
$timeout((v) => {
console.log('a', v);
}, 2000, 7);
const promise = $timeout(() => {
console.log('b');
}, 3000);
promise.catch((reason) => {
console.log(reason);
});
$timeout.cancel(promise);