1. ホーム
  2. javascript

[解決済み] Angular 2の$timeoutに相当するもの

2022-03-01 09:31:21

質問

Angular 2環境で既存のコード(大量)を使用しなければなりません。そのコードでは $timeout サービス AngularJS 1.xで使用されている他の様々なサービスとは対照的に、Angular2での $timeout サービスです。

は、その Angularドキュメント を使用したサービスについての言及はないようです。 timeout -のようなものが名前に含まれています。記事 AngularJSからのアップグレード は、私が直面しているシナリオについて言及しています。

のようなAngularJSのビルトインサービスにアクセスしたいかもしれません。 $location または $timeout .

残念ながら、この記事では、次の例のように、それらの特定のサービスにアクセスする方法を実際に説明していません。 HeroesService AngularJS 1.xで提供される依存関係のないサービスを想定しています。

などの記事は これ を使用することを推奨します。 setTimeout 機能 の能力に見合ったものではありません。 $timeout のサービスもあります。

を再現するにはどうしたらいいのでしょうか? $timeout の機能をAngular 2環境で使用できますか?

EDIT: 回答でも指摘されているように、ネイティブの setTimeout 関数は、Angular 2を使用する場合には関係ありません。その場合、もし私が完全な $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ではもう特別なサービスを使う必要はありません。これは ゾーン 具体的には 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);