在Scala中,我可以获取值列表,在它们之间映射未来返回的函数,并返回将将这些期货的值收集到列表中的未来(或者在第一个错误时失败)。更具体地说:
import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
def doSomething(i: Int): Future[Int] = future(i + 1) // Not really doing much.
val incremented = Future.traverse(List(1, 2, 3))(doSomething)
在这种情况下,结果将只是递增列表:
scala> incremented.onSuccess { case xs => println(xs) }
List(2, 3, 4)
我也可以创建一个期货清单,然后将它们变成一个包含相同结果的未来:
val incremented = Future.sequence(List(1, 2, 3).map(doSomething))
这会给我同样的东西,但它会创建一个额外的中间集合,并且会更加嘈杂。
我希望使用Q中的承诺执行此类操作,看起来Q.all
或多或少sequence
:
function doSomething(i) { return Q.fcall(function () { return i + 1; }); }
Q.all([1, 2, 3].map(doSomething)).then(function (xs) { console.log(xs) })
我有没有办法写一个更像traverse
的版本?这是一个基本的操作似乎必须有一种方法可以做到这一点,但这是我第一个下午的Q,我仍在处理fcall
和朋友的所有重载。
答案 0 :(得分:1)
并非直接回答您的问题,但AngularJS使用了极其简化的Q版本($q),因此您必须自己实施此行为。
这是一种方法:
var traverse = function(fn /*values*/) {
var values = _.rest(arguments);
var promises = _.map(values, fn);
return $q.all(promises);
};
完整示例:http://plnkr.co/edit/PGp7QbQYMjOknJwSEn8E
或者使用Scala中的单独参数列表:
var traverse = function(/*values*/) {
var values = arguments;
return function(fn) {
var promises = _.map(values, fn);
return $q.all(promises);
}
};
答案 1 :(得分:0)
您可以对方法使用Promise Chaining + Static值(而不是promises),并执行以下操作:
Q.all([1,2,3])
.then(function(xs) {
return _(xs).map(doSomething)
})
.then(function(xs) {
console.log(xs);
});
如果你想要一个像这样的遍历函数,你可以自己轻松实现它
希望它有所帮助!