在我的应用中,我从USB设备接收包裹。发送命令后,我应该每N
ms调用一次接收函数来获取所有数据包。
我用承诺创建了链:
var packagesCount = 10;
var chain = $q.when();
for (var i=0; i<packagesCount; i++) {
chain = chain.then(hidRead((packagesCount-i)*1000));
}
chain.then(function () {
console.log("all finished")
}, function (reason) {
console.log(reason);
console.log(reason)
});
我的read函数包含两个async
函数:
function hidRead(ms) {
var defer = $q.defer();
setTimeout(function(){
if (self.connectionId) {
chrome.hid.receive(self.connectionId, function (reportId, data){
console.log(data);
defer.resolve();
});
} else {
defer.reject(new Error('Connection failed'));
}
}, ms);
return function() {
return defer.promise;
};
}
我的fail
函数仅在完成所有Timeouts
函数后调用。但我需要立即拒绝它。如果我们失去了连接并被拒绝,我们应该停止链执行。
我尝试添加catch
,循环失败回调,任何帮助。
答案 0 :(得分:0)
hidRead
只是重新创建$timeout
的功能,但问题是链创建时会调用hidRead
,这意味着所有超时都将无条件执行。为避免这种情况,hidRead
应返回回调函数。
如果chrome.hid.receive(...)
不是异步或延迟绝不高于ms
,则基本上类似于
function hidRead(ms) {
return function () {
return $timeout(function () {
if (self.connectionId) {
chrome.hid.receive(self.connectionId, function (reportId, data){
console.log(data);
});
} else {
return $q.reject(new Error('Connection failed'));
}
});
}
}
否则,可能会另外使用$q.defer()
,原始代码将更改为
function hidRead(ms) {
return function () {
var defer = $q.defer();
setTimeout(...);
return defer.promise;
}
}
上面的代码将在每次迭代时触发摘要。如果没有必要或产生性能问题,$q
可能会更改为原生Promise
或Bluebird,后者具有Promise.delay
,这在此类情况下非常有用。