Я работаю над страницей, использующей 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
. Иногда элемент отправляется на один сервер. Иногда он будет отправлен на несколько серверов. В любом случае, я не знаю, когда элемент будет выполнен "отправлен". По этой причине я использую обратный вызов для управления очередью. Когда элемент выполняется "отправлено", я хочу удалить его из очереди. Мне нужно использовать тайм-аут или интервал, чтобы проверить, заблокирована ли очередь или нет. Если он не заблокирован, я хочу удалить элемент из очереди. Эта проверка добавляет еще один уровень вложенности, который меня путает.
Моя проблема в том, что я не верю, что объем индекса работает так, как я ожидал. Я чувствую, что у меня состояние гонки. Я основываю это на том факте, что я написал следующий тест Жасмина:
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
Похоже, что элементы не будут удалены, как я ожидал. Неужели я нахожусь в основе моего подхода к управлению очередью? Что я делаю неправильно?
Спасибо за любую помощь.