2016-05-12 6 views
0

私は新しい開発者です。約束事が5秒後に解決されていないかどうかを確認しようとしています。新しいディレクティブ/サービス/ファクトリを作成せずにこれを行う最も読みやすい方法は何ですか?これは私が試したことです、私の主な質問は、私は正しい時間に、約束変数がインスタンス化される間隔を設定ですか?リクエスト/約束が5秒以上かかっているかどうかを確認する方法、角度js

$scope.promiseTimeLimit = false; 
     //if the promise does not return within 5 seconds, show a "service down" warning. 
     var promise = service.checkValidRailCar($scope.railcar.number, $scope.railcar.initials); 

     $interval(function() { 
     $scope.promiseTimeLimit = true 
     }, 5000) 

     if ($scope.promiseTimeLimit) { 
     $scope.message = { 
      content: [{ 
      title: '', 
      msg: 'The Service Is Down' 
      }], 
      type: 'error' 
     }; 
     return; 
     } 
     promise.then(function (data) { 
     if (!data.valid) { 
      $scope.invalidData = true; 
      $scope.message = { 
      content: [{ 
       title: '', 
       msg: 'Invalid: This is not a valid data and can not be created.' 
      }], 
      type: 'error' 
      }; 
     } else { 
      $scope.invalidData = false; 
     } 
     }) 

答えて

1

はい、約束がインスタンス化された後、正しく間隔を設定しました。しかし、私はここで$intervalを使いたいとは思わない。 $timeoutを使用します。 $intervalのコールバック関数は、$intervalをクリアしない限り、何度も呼び出されます。 $timeoutのコールバック関数は1回だけ呼び出されます。約束が5秒で解決された場合は、一度だけチェックしたい場合は、$timeoutを使用してください。

2つ目は、次のコードについてです:

if ($scope.promiseTimeLimit) { 
    $scope.message = { 
     content: [{ 
     title: '', 
     msg: 'The Service Is Down' 
     }], 
     type: 'error' 
    }; 
    return; 
} 

あなたは$タイムアウト機能の内部で、このコードを維持する必要があります。理解を深めるために、変数名$scope.promiseTimeLimit$scope.promiseCompleteに変更し、$scope.promiseComplete = falseとして初期化しました。

$timeout(function() { 
    if(!$scope.promiseComplete) { 
     $scope.message = { 
      content: [{ 
      title: '', 
      msg: 'The Service Is Down' 
      }], 
      type: 'error' 
     }; 
    } 
}, 5000); 

はその後、promise.then機能(解決)で、あなたがtrueに$scope.promiseCompleteを設定する必要があります。

promise.then(function (data) { 
    $scope.promiseComplete = true; 
    if (!data.valid) { 
     ... 
}) 

ここでは何が起こっていますか? $ timeoutコールバック関数は5秒後に呼び出されます。 $scope.promiseCompleteがfalseであるかどうかをチェックします。 falseの場合、警告メッセージを生成します。真の場合、何もしないでください。 promise.thenでは、$scope.promiseCompleteをtrueに設定しています。したがって、$ timeoutコールバック関数が呼び出される前にpromise.then関数(resolve)が$scope.promiseCompleteをtrueに設定すると、約束は5秒前に完了します。

私は、この動作を理解するためのサンプルプランナーを作成しました。あなたはHEREを見ることができます。

0

IMHOでは、約束のタイムアウトは拒否として実装されるべきであり、約束のように可能な限り低いレベルでインプレメントされるべきです。

実際に、非同期タイムアウトは、レースで、window.setTimeout()の約束であり、呼び出したい非同期サービス方法は事実上です。

あなたは、たとえば、このようにそれを書くことができます:

service.checkValidRailCarWithTimeout = function(t, railcarNumber, railcarInitials) { 
    // range checks 
    if(t === undefined || railcarNumber === undefined || railcarInitials === undefined) { 
     return $q.reject(new RangeError('Invalid parameter(s)')); 
    } 
    // race - timeout versus service call 
    return $q(function(resolve, reject) { 
     var tRef = window.setTimeout(function() { 
      reject(new Error('The Service Is Down'); 
     }, t); 
     function kill() { 
      window.clearTimeout(tRef); 
     }; 
     service.checkValidRailCar(railcarNumber, railcarInitials).then(resolve, reject).then(kill, kill); 
    }); 
}; 

を、次のように呼び出します。

var promise = service.checkValidRailCarWithTimeout(5000, $scope.railcar.number, $scope.railcar.initials).then(function(data) { 
    $scope.invalidData = !data.valid; 
    if (!data.valid) { 
     throw new Error('Invalid: This is not a valid data and can not be created.'); 
    } 
}).catch(function(error) { 
    $scope.message = { 
     content: [{ 
      title: '', 
      msg: error.message 
     }], 
     type: 'error' 
    }; 
}); 

注:

  • $scope.promiseTimeLimitの必要性が
  • kill()を消えます厳密には必須ではありません彼らのレースを失った潜在的なタイムアウトをクリアすることで物事をきれいに保ちます。
  • error
によって配信されるメッセージは、 $scope.message = ...の式に表示されます。
関連する問題