Можно ли приостановить функцию до «приёма сигнала»?
Здравствуйте.
Допустим, у меня есть функция turn(), которая позволяет сделать ход за отряд в игре. Функция turn1() вызывает функции startMove() и startShoot(), которые расставляют на поле необходимые маркеры, включают Drag'N'Drop для солдатиков, выводят интерфейсы для выбора оружия для стрельбы и т. д. Есть так же функции endMove() и endShoot() для того, чтобы убирать весь лишний интерфейс от каждой из функций как только пользователь сделает нужное действие.
Действия нужно сделать в строгом порядке - сначала нужно чтобы turn1() вызвал startMove(), дождался, когда сработает endMove(), и только затем продолжила выполняться, вызвав startShoot(). Добавить вызов startShoot() в конец endMove() нельзя - есть, например, функция turn2(), которая предполагает вызов двух endMove() подряд. Собственно в этом и вопрос - есть ли какой-то способ "заморозить" функцию до поступления сигнала извне, и если нет, то как можно обойти эту проблему?
const moveQueue = {
queue: [],
index: 0,
create() {
let endMoveCallback;
// создаём висячий промис и присваиваем его разрешение в endMoveCallback
const movePending = new Promise(resolve => endMoveCallback = resolve);
// index чисто для лога
endMoveCallback.index = this.index++;
// добавляем в очередь
this.queue.push(endMoveCallback);
// возвращаем проис ждущий вызова endMoveCallback
return movePending;
},
last() {
// забираем из очереди последнее добавленное
return this.queue.pop();
}
}
async function turn() {
await startMove();
await startShoot();
}
function startMove() {
console.log('startMove', moveQueue.index);
return moveQueue.create();
}
function endMove() {
const activeMoveEnd = moveQueue.last();
if (activeMoveEnd) {
console.log('endMove', activeMoveEnd.index)
activeMoveEnd();
} else {
onsole.error('`endMove` called when there are no active moves')
}
}
function startShoot() {
console.log('startShoot');
}
turn();
setTimeout(() => endMove(), 1000)
Но скорее всего у тебя что-то не то с архитектурой, и тебе лучше будет почитать книжки по геймдеву.