AngularJS
$ qサービスによる角度の約束
サーチ…
$ q.allを使用して複数の約束を処理する
$q.all
関数を使用して、約束事の配列が正常に解決され、解決されたデータをフェッチした後に.then
メソッドを呼び出すことができます。
例:
JS:
$scope.data = []
$q.all([
$http.get("data.json"),
$http.get("more-data.json"),
]).then(function(responses) {
$scope.data = responses.map((resp) => resp.data);
});
上記のコードが実行される$http.get
両方をするとき、ローカルのJSONファイル内のデータの2倍をget
完全な方法を、彼らはそれに関連する約束を解決し、アレイ内のすべての約束は解決されたときに、 .then
方法は、内部の両方の約束データで始まるresponses
配列引数。
データはテンプレートに表示されるようにマップされます
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"
}]
$ qコンストラクタを使用して約束を作成する
$q
コンストラクタ関数は、コールバックを使用して結果を返す非同期APIから約束を作成するために使用されます。
$ q(function(resolve、reject){...})
コンストラクタ関数は、約束を解決または拒否するために使用される関数であるresolve
とreject
2つの引数で呼び出される関数を受け取ります。
例1:
function $timeout(fn, delay) {
return = $q(function(resolve, reject) {
setTimeout(function() {
try {
let r = fn();
resolve(r);
}
catch (e) {
reject(e);
}
}, delay);
};
}
上記の例は、 WindowTimers.setTimeout APIから約束を作成します 。 AngularJSフレームワークは、この関数のより精巧なバージョンを提供します。使用方法については、 AngularJS $ timeoutサービスAPIリファレンスを参照してください 。
例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);
}
});
}
上記のコードは、約束された除算関数を示しています。計算が不可能な場合は、結果と共に約束を返し、理由があれば拒否します。
その後、呼び出して使用することができます.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.
})
$ q.deferを使用した操作の遅延
$q.defer
を使用することにより、未定の約束オブジェクトを現在持っている間に$q
を使用して将来の操作を延期することができます。将来、解決または拒否する約束を作成します。
$q.defer
を使用して約束を返すかどうか(または返さなかった)既存のルーチンを約束するため、このメソッドは$q
コンストラクタの使用と同じではありません。
例:
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) {})
常に、
deferred.promise
オブジェクトを返すか、エラーを.then
可能性があります。あなたは常にあなたの繰延オブジェクトまたは解決するか、拒否していることを確認してください
.then
実行できない場合があり、あなたはメモリリークの危険を冒します
$ qサービスで角度の約束を使う
$q
は、非同期関数を実行し、処理が終了したときに戻り値(または例外)を使用するのに役立つビルトインサービスです。
$q
は$rootScope.Scope
モデルの観測メカニズムと統合されています。これは、モデルへの解像度や拒否がより速く伝播し、不必要なブラウザの再描画を避け、UIがちらつくことを意味します。
この例では、プロミスオブジェクトを返すファクトリgetMyData
を呼び出します。オブジェクトがresolved
と、乱数が返されます。 rejected
場合は、2秒後にエラーメッセージとともに拒否を返します。
角度のある工場で
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;
}
}
電話で約束を使う
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())
})
})
約束を使用するには、 $q
を依存関係として注入します。ここでgetMyData
ファクトリに$q
をgetMyData
ました。
var defer = $q.defer();
$q.defer()
呼び出すことによって、遅延の新しいインスタンスが構築されます。
遅延オブジェクトは、単に約束を明らかにするオブジェクトであり、約束を解決するための関連する方法です。これは$q.deferred()
関数を使って構築され、 resolve()
、 reject()
、 notify()
3つの主要なメソッドを公開します。
-
resolve(value)
- 派生した約束を値で解決します。 -
reject(reason)
- 派生した約束をその理由で拒否します。 -
notify(value)
- 約束の実行状況に関する更新を提供します。これは、約束が解決または拒絶される前に複数回呼び出されることがあります。
プロパティ
関連付けられた約束オブジェクトは、約束のプロパティを介してアクセスされます。 promise
- {Promise} - この延期に関連付けられたオブジェクトを約束します。
繰延インスタンスが作成され、呼び出すことによって取得することができたときに新しい約束インスタンスが作成されdeferred.promise
。
promise
オブジェクトの目的は、完了したときに利害関係者が遅延タスクの結果にアクセスできるようにすることです。
約束方法 -
then(successCallback, [errorCallback], [notifyCallback])
- 約束が解決されたかどうかにかかわらず、結果が利用可能になるとすぐに、成功またはエラーのコールバックを非同期に呼び出します。コールバックは、単一の引数、つまり結果または拒否の理由で呼び出されます。さらに、通知コールバックは、約束が解決または拒否される前に、進行通知を提供するために0回以上呼び出されることがあります。catch(errorCallback)
- promise.then(null、errorCallback)の短縮形です。finally(callback, notifyCallback)
- 約束の履行または拒否のいずれかを観察することができますが、最終的な値を変更することはありません。
約束の最も強力な特徴の1つは、それらを連鎖させる能力です。これにより、データは鎖を通って流れ、各ステップで操作され、突然変異される。これは、次の例で示されます。
例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);
});
$ q.when()を使って簡単な値を約束する
もしあなたが必要とするのは、その価値を約束するものであるならば、ここのような長い構文を使う必要はありません:
//OVERLY VERBOSE
var defer;
defer = $q.defer();
defer.resolve(['one', 'two']);
return defer.promise;
この場合、次のように書くことができます。
//BETTER
return $q.when(['one', 'two']);
$ q.whenとその別名$ q.resolve
値または(第三者)可能な約束事である可能性のあるオブジェクトを$ q約束にラップします。これは、約束事であろうとなかろうとしているオブジェクトを扱っている場合、または約束が信頼できないソースから来た場合に便利です。
AngularJS v1.4.1のリリースで
また、ES6の整合性のある別名resolve
使用することもできresolve
//ABSOLUTELY THE SAME AS when
return $q.resolve(['one', 'two'])
$ q遅延防止パターンを避ける
このアンチパターンを避ける
var myDeferred = $q.defer(); $http(config).then(function(res) { myDeferred.resolve(res); }, function(error) { myDeferred.reject(error); }); return myDeferred.promise;
$ httpサービスがすでに約束を返すので、$ $q.defer
約束を$q.defer
必要はありません。
//INSTEAD
return $http(config);
$ httpサービスによって作成された約束を返すだけです。