我正在处理一个使用JavaScript管理队列的页面。我的挑战是我的代码包含嵌套的回调函数。这些嵌套的回调函数让我对队列的作用域感到困惑。目前,我的代码如下:
function MyApp() {}
module.exports = MyApp;
MyApp.myQueue = [];
MyApp.queueIsLocked = false;
MyApp.enqueue = function(item, onSuccess, onFailure) {
if (!MyApp.queueIsLocked) {
MyApp.queueIsLocked = true;
MyApp.myQueue.push(item);
MyApp.queueIsLocked = false;
item.send(
function() {
console.log('item: ' + item.id);
MyApp.queueIsLocked = true;
MyApp.findItemById(item.id,
function(index) {
if (index !== -1) {
MyApp.myQueue.splice(index, 1);
MyApp.queueIsLocked = false;
if (onSuccess) {
onSuccess(item.id);
}
}
}
);
},
function() {
alert('Unable to send item to the server.');
if (onFailure) {
onFailure();
}
}
);
}
};
MyApp.findItemById = function(id, onComplete) {
var index = -1;
if (MyApp.queueIsLocked) {
setTimeout(function() {
// Attempt to find the index again.
}, 100);
} else {
MyApp.queueIsLocked = true;
for (var i=0; i<MyApp.myQueue.length; i++) {
if (MyApp.myQueue[i].id === id) {
index = i;
break;
}
}
}
if (onComplete) {
onComplete(index);
}
};
send
函数根据item
的细节表现不同。有时项目将被发送到一个服务器,有时将被发送到多个服务器。无论哪种方式,我都不知道什么时候项目将完成“发送”。因此,我使用回调来管理队列。当项目完成“发送”时,我想将其从队列中删除。我需要使用超时或间隔来检查队列是否已锁定。如果没有被锁定,我想从队列中删除该项。这个检查添加了另一层嵌套,让我感到困惑。
我的挑战是,我认为索引的范围不像我预期的那样工作。我觉得我遇到了竞争条件。我基于以下Jasmine测试编写:
describe('Queue', function() {
describe('Approach 1', function() {
it('should do something', function() {
MyApp.enqueue({id:'QRA', text:'Test A'});
});
});
describe('Approach 2', function() {
it('should successfully queue and dequeue items', function() {
MyApp.enqueue({id:'WX1', text:'Test 1'});
MyApp.enqueue({id:'QV2', text:'Test 2'});
MyApp.enqueue({id:'ZE3', text:'Test 3'});
});
});
});
当我执行这个测试时,在控制台窗口中看到以下内容:item: QRA index: 1
item: WX1 index: 2
item: QV2 index: 3
item: ZE3 index: 4
就像这些项目没有按照我预期的出队。我的队列管理方式是不是错了?我做错了什么?
感谢任何帮助。