Я очень новичок в обещаниях. Мне нужен мой сервер для ожидания сокетных подключений от внешнего API и от подключений клиентов браузера. Внешний API-интерфейс отправляет на сервер несколько объектов (в данном примере 4), которые принимаются в качестве обещания и вызывают функцию, которая ожидает обещание. Для каждого объекта, полученного обещанием, клиент браузера может установить соединение (обещание) и присоединиться к игре.
У меня есть функция, которая должна ждать заполнения переменных этими двумя обещаниями. Он успешно ожидает внешних объектов API, но никогда не получает обещание указать, что правильное число клиентов установило соединения.
Я обернул сокет прослушиванием внешних объектов API в обещание, так как оно будет отправлено только один раз. Я также вызываю функцию, которая обрабатывает два обещания здесь, поскольку она, кажется, не работает где-либо еще.
//HANDLER FOR GAME OBJECT SENT FROM MAX API
const maxPromise = new Promise ((resolve) => {
socket.on("dictData", async (data)=>{
try {
let {songName, level, imageArr} = data;
let [imageObj] = imageArr;
gameVars.songName = songName;
gameVars.level = level;
let gameObject = {};
for (let obj in imageArr) {
let objectId = imageArr[obj].name;
gameObject.objectId = objectId;
gameObject.path = imageObj.path;
// gameObject.files = imageObj.imagePath;
gameState.totalServerCount ++;
gameState.serverList.push({gameObject});
}
resolve(gameState.serverList) //resolve the promise with the array of objects
sendData()
}
catch (e) {
console.error(e)
}
});
});
Я также обернул прослушиватель req клиента в обещание, потому что после бесчисленных попыток вложить обещание внутрь это было единственное решение, которое не вернуло фактический сокет как обещание, поэтому я считаю, что это, вероятно, самое близкое решение для меня.
Это обещание должно разрешаться только при одинаковом количестве клиентских подключений. поскольку есть объекты сервера, полученные в первом обещании. Я тестирую, просто подключив 4 открытые вкладки к localhost: 3000.
//HANDLER FOR CLIENT REQUEST TO JOIN GAME
const playerPromise = new Promise ((resolve, reject) => {
socket.on('joinGame', async () => {
try {
gameState.totalPlayerCount++;
gameState.playerList.push(socket.id)
switch (true) {
case gameState.totalPlayerCount < gameState.totalServerCount :
console.log("Not enough players", gameState.totalPlayerCount)
break;
case gameState.totalPlayerCount <= gameState.totalServerCount :
console.log("Counts are equal", gameState)
readyPlayers = true;
resolve(gameState.playerList)
break;
case gameState.totalServerCount == 0 :
console.log("Server not ready", gameState)
break;
default :
console.log("Too many players", gameState.totalPlayerCount)
reject("Too many players", gameState.playerList)
}
}
catch(e) {
console.error(e);
}
})
})
Функция sendData () регистрирует 1-й и 2-й тесты на консоли, но не 3-й.
async function sendData() {
try {
console.log("TEST1")
const dataMax = await maxPromise;
console.log("TEST2", dataMax)
const dataPlay = await playerPromise;
console.log("TEST3", dataPlay)
for (var key in await dataPlay) {
io.to(dataPlay[key]).emit('gameData', dataPlay[key]);
}
}
catch(e) {
console.error(e)
}
};
Я просматривал все другие подобные посты по stackoverflow и онлайн, но не могу найти никакого решения для этого или где я ошибаюсь. Я также разработал вышеупомянутое решение с минимальным знанием socket.io и обещаний, так что есть лучший / более чистый способ сделать выше, пожалуйста, дайте мне знать.
РЕДАКТИРОВАТЬ: это мое текущее решение, использующее только одно обещание, но теперь обещание не заполняется вообще в функции отправки:
//HANDLER FOR GAME OBJECT SENT FROM MAX API
const maxPromise = new Promise ((resolve) => {
socket.on("dictData", async (data)=>{
try {
let {songName, level, imageArr} = data;
let [imageObj] = imageArr;
gameVars.songName = songName;
gameVars.level = level;
let gameObject = {};
for (let obj in imageArr) {
let objectId = imageArr[obj].name;
gameObject.objectId = objectId;
gameObject.path = imageObj.path;
gameState.totalServerCount ++;
gameState.serverList.push({gameObject});
}
resolve(gameState.serverList)
}
catch (e) {
console.error(e)
}
});
});
async function sendData(playerData) {
try {
console.log("TEST1")
const dataMax = await maxPromise;
console.log("TEST2")
for (var key in await playerData) {
io.to(playerData[key]).emit('gameData', dataMax);
}
}
catch(e) {
console.error(e)
}
};
SendData () вызывается в обработчике сокета клиента, который просто передает массив соединений как playerData. «TEST2» никогда не регистрируется.
Учитывая, что обещание maxPromise является глобальным, разве оно не сможет получить доступ к его значению?