Promiseライブラリ[〜#〜] q [〜#〜]では、次のようにして、promiseを順番にチェーンできます。
var items = ['one', 'two', 'three'];
var chain = Q();
items.forEach(function (el) {
chain = chain.then(foo(el));
});
return chain;
ただし、以下は$ qでは機能しません。
var items = ['one', 'two', 'three'];
var chain = $q();
items.forEach(function (el) {
chain = chain.then(foo(el));
});
return chain;
単に$ q.when()関数を使用します:
var items = ['one', 'two', 'three'];
var chain = $q.when();
items.forEach(function (el) {
chain = chain.then(foo(el));
});
return chain;
注:fooはファクトリでなければなりません。
function setTimeoutPromise(ms) {
var defer = $q.defer();
setTimeout(defer.resolve, ms);
return defer.promise;
}
function foo(item, ms) {
return function() {
return setTimeoutPromise(ms).then(function () {
console.log(item);
});
};
}
var items = ['one', 'two', 'three'];
var chain = $q.when();
items.forEach(function (el, i) {
chain = chain.then(foo(el, (items.length - i)*1000));
});
return chain;
Redgeoff、あなた自身の答えは、私がを使って配列を連鎖された一連のpromiseに変換する方法です。
緊急デファクトパターンは次のとおりです。
_function doAsyncSeries(arr) {
return arr.reduce(function (promise, item) {
return promise.then(function(result) {
return doSomethingAsync(result, item);
});
}, $q.when(initialValue));
}
//then
var items = ['x', 'y', 'z'];
doAsyncSeries(items).then(...);
_
ノート:
.reduce
_は、ライブラリの一部ではなく、未加工のJavaScriptです。result
は以前の非同期の結果/データであり、完全を期すために含まれています。最初のresult
はinitialValue
です。 「結果」を渡す必要がない場合は、単に省略します。$q.when(initialValue)
を調整します。doSomethingAsync
はfoo
(またはfoo()が返すもの)-いずれの場合も関数です。あなたが私のような人なら、そのパターンは一見、突き通せないクラッジのように見えますが、目が同調すると、それを古い友人と見なし始めます。
編集
以下の demo は、上記の推奨パターンが実際にdoSomethingAsync()
呼び出しを順番に実行することを示すために設計されており、以下のコメントで提案されているようにチェーンを構築している間はすぐには実行されません。
これを持っている:
let items = ['one', 'two', 'three'];
1行(まあ、読みやすくするために3行):
return items
.map(item => foo.bind(null, item))
.reduce($q.when, $q.resolve());
var when = $q.when();
for(var i = 0; i < 10; i++){
(function() {
chain = when.then(function() {
return $http.get('/data');
});
})(i);
}
多分 redgeoffの答え よりも簡単な方法で、自動化する必要がない場合は、$q.when()
を.then()
と組み合わせて使用してプロミスをチェーンすることができます。 この投稿 の始まり。 return $q.when() .then(function(){ return promise1; }) .then(function(){ return promise2; });
私はangular.bind
(またはFunction.prototype.bind
)を使用してpromiseを返す関数を準備し、reduceショートカットを使用してそれらをチェーンにリンクすることを好みます。例えば
// getNumber resolves with given number
var get2 = getNumber.bind(null, 2);
var get3 = getNumber.bind(null, 3);
[get2, get3].reduce(function (chain, fn) {
return chain.then(fn);
}, $q.when())
.then(function (value) {
console.log('chain value =', value);
}).done();
// prints 3 (the last value)
正解です。しかし、私は代替案を提供すると思いました。頻繁にプロミスを連続的にチェーンしている場合は、$ q.serialに興味があるかもしれません。
var items = ['one', 'two', 'three'];
var tasks = items.map(function (el) {
return function () { foo(el, (items.length - i)*1000)); });
});
$q.serial(tasks);
function setTimeoutPromise(ms) {
var defer = $q.defer();
setTimeout(defer.resolve, ms);
return defer.promise;
}
function foo(item, ms) {
return function() {
return setTimeoutPromise(ms).then(function () {
console.log(item);
});
};
}