我使用mbostock/queue排队很少的异步操作。它更多的是速率限制(UI生成很少的事件,后端可以缓慢地处理它),并且还确保它们按顺序处理。我像
一样使用它function request(d, cb) {
//some async oper
add.then(function(){
cb(null, "finished ")
})
}
var addQ = queue(1);
addQ.defer(request) //called by few req at higher rates generated by UI
我已经使用angular.js $ q进行异步操作。那么,我是否必须使用mbostock/queue
,或者我可以使用$q
建立一个队列(精神https://github.com/kriskowal/q)
感谢。
答案 0 :(得分:3)
是的,可以 使用Angular的$ q构建一个链式队列!下面是一个示例,向您展示如何使用递归来创建任意长度的队列。每个帖子都是连续发生的(一个接一个)。第二篇文章将在第一篇文章完成后才开始。
这在写入数据库时很有用。如果数据库在后端没有自己的队列,并且您同时进行多次写入,您可能会发现并非所有数据都已保存!
我添加了Plunkr example来演示此代码。
$scope.setData = function (data) {
// This array will hold the n-length queue
var promiseStack = [];
// Create a new promise (don't fire it yet)
function newPromise (key, data) {
return function () {
var deferred = $q.defer();
var postData = {};
postData[key] = data;
// Post the the data ($http returns a promise)
$http.post($scope.postPath, postData)
.then(function (response) {
// When the $http promise resolves, we also
// resolve the queued promise that contains it
deferred.resolve(response);
}, function (reason) {
deferred.reject(reason);
});
return deferred.promise;
};
}
// Loop through data creating our queue of promises
for (var key in data) {
promiseStack.push(newPromise(key, data[key]));
}
// Fire the first promise in the queue
var fire = function () {
// If the queue has remaining items...
return promiseStack.length &&
// Remove the first promise from the array
// and execute it
promiseStack.shift()()
// When that promise resolves, fire the next
// promise in our queue
.then(function () {
return fire();
});
};
// Begin the queue
return fire();
};
您可以使用简单的功能开始排队。为了演示,我将一个充满键的对象传递给一个函数,该函数将这些键分成单独的帖子,然后将它们发送到Henry's HTTP Post Dumping Server。 (谢谢Henry!)
$scope.beginQueue = function () {
$scope.setData({
a: 0,
b: 1,
/* ... all the other letters of the alphabet ... */
y: 24,
z: 25
}).then(function () {
console.log('Everything was saved!');
}).catch(function (reason) {
console.warn(reason);
});
};
如果您想试用此代码,可以使用Plunkr example的链接。
答案 1 :(得分:1)
简短的回答是否定的,您不需要额外的库。 Promise.then()足够"原子"。答案很长:值得制作一个queue()函数来保持代码DRY。 Bluebird-promises似乎非常完整,但这里的内容基于AngularJS的$ q。
如果我正在制作.queue(),我也希望它能够处理错误。
这是一个有角度的服务工厂,还有一些用例:
/**
* Simple promise factory
*/
angular.module('app').factory('P', function($q) {
var P = $q;
// Make a promise
P.then = function(obj) {
return $q.when(obj);
};
// Take a promise. Queue 'action'. On 'action' faulure, run 'error' and continue.
P.queue = function(promise, action, error) {
return promise.then(action).catch(error);
};
// Oook! Monkey patch .queue() onto a $q promise.
P.startQueue = function(obj) {
var promise = $q.when(obj);
promise.queue = function(action, error) {
return promise.then(action).catch(error);
};
return promise;
};
return P;
});
如何使用它:
.run(function($state, YouReallyNeedJustQorP, $q, P) {
// Use a $q promise. Queue actions with P
// Make a regular old promise
var myPromise = $q.when('plain old promise');
// use P to queue an action on myPromise
P.queue(myPromise, function() { return console.log('myPromise: do something clever'); });
// use P to queue an action
P.queue(myPromise, function() {
throw console.log('myPromise: do something dangerous');
}, function() {
return console.log('myPromise: risks must be taken!');
});
// use P to queue an action
P.queue(myPromise, function() { return console.log('myPromise: never quit'); });
// Same thing, but make a special promise with P
var myQueue = P.startQueue(myPromise);
// use P to queue an action
myQueue.queue(function() { return console.log('myQueue: do something clever'); });
// use P to queue an action
myQueue.queue(function() {
throw console.log('myQueue: do something hard');
}, function() {
return console.log('myQueue: hard is interesting!');
});
// use P to queue an action
myQueue.queue(function() { return console.log('myQueue: no easy days'); });
答案 2 :(得分:0)
Angular的$q
实现允许您链接promises,然后根据您自己的逻辑处理这些promise的解析。这些方法与mbostock/queue
略有不同,但目的是相同的。创建一个函数,确定如何解决您的deferred(创建一个promise),然后将这些函数提供给更高级别的控制器/服务以进行特定的解决方案处理。
Angular使用$q.defer()
返回promise对象,然后可以按照您希望在应用程序逻辑中的顺序调用它。 (甚至跳过,变异,截获等......)。
我会抛弃一些代码,但我发现egghead.io上的这个7分钟视频是最好的简短演示:https://egghead.io/lessons/angularjs-chained-promises,它会更好地解释FAR。托马斯(演示者)构建了一个非常小的飞行仪表板应用程序,用于排队天气和飞行数据,以及当用户查询其迭代时排队的进程。 ThomasBurleson/angularjs-FlightDashboard
我将在codepen上设置一个较小的演示,使用'在餐馆吃饭'的情况来证明这个概念:http://codepen.io/LongLiveCHIEF/pen/uLyHx
此处的代码示例: