Mis*_*hko 11 javascript promise angularjs q angular-promise
鉴于以下功能:
function isGood(number) {
var defer = $q.defer();
$timeout(function() {
if (<some condition on number>) {
defer.resolve();
} else {
defer.reject();
}
}, 100);
return defer.promise;
}
Run Code Online (Sandbox Code Playgroud)
和一组数字(例如[3, 9, 17, 26, 89]),我想找到第一个 "好"的数字.我希望能够做到这一点:
var arr = [3, 9, 17, 26, 89];
findGoodNumber(arr).then(function(goodNumber) {
console.log('Good number found: ' + goodNumber);
}, function() {
console.log('No good numbers found');
});
Run Code Online (Sandbox Code Playgroud)
这是一个可能的递归版本来实现这个: DEMO
function findGoodNumber(numbers) {
var defer = $q.defer();
if (numbers.length === 0) {
defer.reject();
} else {
var num = numbers.shift();
isGood(num).then(function() {
defer.resolve(num);
}, function() {
findGoodNumber(numbers).then(defer.resolve, defer.reject)
});
}
return defer.promise;
}
Run Code Online (Sandbox Code Playgroud)
我想知道是否有更好的(可能是非递归的)方式?
我想知道是否有更好的方法?
是.避免延迟反模式!
function isGood(number) {
return $timeout(function() {
if (<some condition on number>) {
return number; // Resolve with the number, simplifies code below
} else {
throw new Error("…");
}
}, 100);
}
function findGoodNumber(numbers) {
if (numbers.length === 0) {
return $q.reject();
} else {
return isGood(numbers.shift()).catch(function() {
return findGoodNumber(numbers);
});
}
}
Run Code Online (Sandbox Code Playgroud)
也许不是递归的?
你可以制定一个链接大量then调用的循环,但是递归在这里绝对没问题.如果你真的想要循环,它可能看起来像这样:
function findGoodNumber(numbers) {
return numbers.reduce(function(previousFinds, num) {
return previousFinds.catch(function() {
return isGood(num);
});
}, $q.reject());
}
Run Code Online (Sandbox Code Playgroud)
然而,这一点效率较低,因为它总是可以看到numbers."递归"版本将懒惰地评估它,并且如果当前数字不好则仅进行另一次迭代.
也许更快?
您可以isGood并行触发所有检查,并等待第一个完成检查返回.根据isGood实际做的和可并行化的程度,这可能会"更好".但是,它可能会做很多不必要的工作; 您可能想要使用支持取消的promise库.
使用Bluebird库的示例,该库具有专用于此任务的any辅助函数:
function findGoodNumber(numbers) {
return Bluebird.any(numbers.map(isGood))
}
Run Code Online (Sandbox Code Playgroud)