Javascript 我如何使用$q做出递归承诺
假设我有一条规则:Javascript 我如何使用$q做出递归承诺,javascript,angularjs,recursion,timeout,angular-promise,Javascript,Angularjs,Recursion,Timeout,Angular Promise,假设我有一条规则: var count = 0; function isCountFifty() { count++; return 50 === count; } 我想执行iscount50th()50次,每次在下次再次运行此方法之前放置一个$timeout0,直到它达到50并解决承诺 我正在尝试使用angular$q 这是总体外观: var defer = $q.defer(); defer.promise.then(resolveWhenFifty())
var count = 0;
function isCountFifty() {
count++;
return 50 === count;
}
我想执行iscount50th()
50次,每次在下次再次运行此方法之前放置一个$timeout
0,直到它达到50并解决承诺
我正在尝试使用angular$q
这是总体外观:
var defer = $q.defer();
defer.promise.then(resolveWhenFifty())
.then(function () { ... something to do after count reaches 50 ...});
defer.resolve();
我想弄清楚这里应该是什么:
function resolveWhenFifty () {
return function () {
var defer = $q.defer();
if (isCountFifty()) {
defer.resolve();
} else {
$timeout(function () {
... ? WHAT SHOULD BE THE RECURSION HERE ? ...
}
}
return defer.promise;
}
}
我尝试了几种方法,但我一直在迷茫如何使这个递归函数以正确的解析返回正确的承诺,以及如何将所有这些承诺链接在一起。我想这就是您要寻找的。退房 您将获得如下控制台输出:
- 一,
- “超时”
- 二,
- “超时”
- 三,
- “超时”
- 。。。等等李>
- 49
- “超时”
- 五十
- “超时”
- “完成”
var self=this; this.isCount=函数(计数){ 控制台日志(计数); 返回50==计数; } var承诺=[]; 对于(var i=0;i<51;i++)promises.push({ 伯爵:我 }); //同步执行每个承诺 var myFunc=函数(){ 返回承诺.reduce(函数(承诺,项){ return promise.then(函数(){ 返回$q.when( $timeout(函数(){ log('in timeout'); },500), self.iscount五十(item.count)); }); },$q.when()); }; myFunc()。然后(函数(){ console.log('done'); });
- 我已经设法让它工作了。我在plunkr上做了一个演示
我应该更清楚地知道,
iscountfown()
只是一个条件函数的示例,该函数将反复迭代,直到得到解决(超时次数最多)
我附上以下主要概念:
function isCountFifty() {
count++;
return 50 === count;
}
function delay(time) {
return function() {
return $timeout(angular.noop, time);
}
}
function recursion(defer) {
if (isCountFifty()) {
defer.resolve();
} else {
var newDefer = $q.defer();
newDefer.promise.then(delay(50)).then(function() {
recursion(defer);
});
newDefer.resolve();
}
}
var defer = $q.defer();
recursion(defer);
defer.promise.then(function() {
console.log('yay! if I see this message it means I made 50 timeouts of 50 ms each');
return defer.promise;
});
我有一个线索,这段代码可以更有效,但它做了我想要的。可以对代码进行重新分解,以避免使用
$q.defer
angular.module('myApp', []).controller('myController', function($scope, $q, $timeout) {
var _this = this;
var vm = $scope;
vm.recursions = 0;
vm.isResolved = false;
var time = 200;
function waitForClass(count) {
if (count>0) {
vm.recursions++;
return $timeout(function(){return waitForClass(count-1)},time);
} else {
return $q.when(0);
}
}
waitForClass(50).then(function() {
vm.isResolved = true;
return 0;
});
});
$timeout
服务返回承诺,这些承诺可以链接起来
因为调用承诺的.then
方法会返回一个新的派生承诺,所以很容易创建一个承诺链。可以创建任意长度的链,并且由于一个承诺可以用另一个承诺解决(这将进一步推迟其解决),因此可以在链中的任何点暂停/推迟承诺的解决
这似乎是一个XY问题。这是一个学习练习吗?如果不是,什么是真正的用例?如果不是在严格模式下调用
参数。如果不是在严格模式下调用被调用方
,或者如果是在严格模式下调用resolveWhenFifty()
。@charlietfl真正的用例:我有一个div。我想向它添加类x,只有在添加类x之后,我才想向它添加类y。这就是为什么我想检查dom$(element).hasClass(x){$element.addClass('y')},并且我想设置几个超时(最大计数器为10)来检查是否添加了x,然后才添加y如果使用角度方法,这将很简单。。根据数据模型设置ng类。为什么需要检查DOM而不是使用数据模型来驱动DOM中发生的事情?显示更多用于更改class@charlietfl我正在写一个指令来管理动画类。它需要将类放在特定的序列中。我假设我不能使用ng类,因为我的指令的用户可能会使用它,我不想阻止他们这样做。我不认为使用ng类或直接使用DOM有什么区别,但我可能没有意识到这些细微差别。除此之外,我正在努力学习如何履行承诺,这是一个很好的实践。感谢您的回复。我应该更清楚,这不是一个50超时,而是一个应该检查直到解决的条件(超时数未知)。我已经回答了我自己的问题——你可以明白我的意思。
angular.module('myApp', []).controller('myController', function($scope, $q, $timeout) {
var _this = this;
var vm = $scope;
vm.recursions = 0;
vm.isResolved = false;
var time = 200;
function waitForClass(count) {
if (count>0) {
vm.recursions++;
return $timeout(function(){return waitForClass(count-1)},time);
} else {
return $q.when(0);
}
}
waitForClass(50).then(function() {
vm.isResolved = true;
return 0;
});
});