Angular 2環境で(大量の)既存のコードを使用する必要があります。そのコードは、AngularJS 1.xの $timeout
サービス を広範囲に使用しています。コードで使用される他のさまざまなAngularJS 1.xサービスとは対照的に、$timeout
サービスに相当するAngular 2に関する情報を見つけるのに苦労しています。
Angular docs には、名前にtimeout
- somethingが含まれるサービスの言及が含まれていないようです。記事 AngularJS からのアップグレードでは、私が直面しているシナリオに言及しています:
$location
や$timeout
などのAngularJSの組み込みサービスにアクセスしたい場合があります。
残念なことに、この記事では実際にそれらの特定のサービスにアクセスする方法を説明していません。後続の例HeroesService
は、AngularJS 1.xによって提供される依存関係のないサービスを想定しています。
this one などの記事は、ネイティブ setTimeout
function を使用することを提案していますが、$timeout
サービスの機能にも対応していません。
Angular 2環境で$timeout
機能を再現するにはどうすればよいですか?
編集:回答で指摘されているように、Angular 2.を使用する場合、ネイティブのsetTimeout
関数の欠点は関係ありません。その場合、完全な$q
AngularJS 1.xでは、$timeout
関数をほぼ次のように複製できます。
function $timeout(fn, delay) {
var result = $q.defer();
setTimeout(function () {
$q.when(fn()).then(function (v) {
result.resolve(v);
});
}, delay);
return result.promise;
}
setTimeout
ネイティブ関数を使用します。 Angularで特別なサービスを使用する必要はもうありません。これは、 zones 、特に NgZone の導入によるものです。
このような記事では、ネイティブのsetTimeout関数を使用しても$ timeoutサービスの機能に対応していないことが示唆されています。
なぜそう言うのですか? $timeout
サービスの主なタスクは、遅延関数が実行された後にダイジェストを開始することでした。あなたはソースからそれを見ることができます:
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);
Angular zone.js
では、すべての非同期操作をインターセプトし、_-Angularで変更検出を開始します。これは ダイジェストの拡張バージョンの種類 です。
$timeout
を複製する必要がある場合、おおよそ次のようにできます。
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);