我正在使用
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); } };
发送函数根据项目的细节而有所不同.有时,该项目将被发送到一个服务器.有时,它将被发送到多个服务器.无论哪种方式,我不知道什么时候项目将被完成“发送”.因此,我使用回调来管理队列.当项目完成“发送”时,我想将其从队列中删除.我需要使用超时或间隔来检查队列是否被锁定.如果没有锁定,我想从队列中删除该项.这个检查是增加了另一个级别的嵌套,这使我感到困惑.
我的挑战是,我不认为索引的范围正如我所料.我觉得我正在获得比赛条件.我基于这个事实,我写了以下茉莉花测试:
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
它像项目没有像我所期望的那样出现.我在管理队列方式的基础上吗?我究竟做错了什么?
感谢您的协助.
解决方法
以下是您需要思考的一些问题,并回答自己的意图和设计:
>这听起来像队列表示您尝试发送到服务器的项目.您正在将队列中的项目添加到需要发送的队列中,并在成功发送队列后将其删除.
>您是否希望代码同时发送多个项目?例如,将项目A添加到队列中,然后发送.在异步发送A完成之前,项目B被添加到列表中.代码是否尝试在项目A的发送完成之前发送项目B.根据你的代码,听起来就像是的.
看来,你真的不想/需要一个队列,本身,就像你想要一个列表来跟踪哪些项目正在发送的过程. “队列”意味着对象正在以某种FIFO顺序处理.
如果您只想根据id跟踪项目,则可以使用对象.例如:
MyApp.items = {}; MyApp.addItem = function(item){ MyApp.items[item.id] = item; item.send( function(){ // success MyApp.removeItem(item.id) } ); } MyApp.removeItem = function(id){ delete MyApp.items[id]; onSuccess(id); }
另外,我不认为你需要在队列上锁. Javascript是单线程的,所以你永远不会有两个部分的代码尝试在同一时间在队列上操作的情况.当ajax调用异步完成时,您的回调代码将不会实际执行,直到当前正在执行的其他代码完成.