[英]Javascript execution order when using if statements
我是這里的新手,我為任何無知道歉。 我正在嘗試使用 node.js 創建一個供個人使用的家庭不和游戲,並表示為服務器和 socket.io 用於客戶端之間的通信。 我遇到了這個特殊的 function 的問題,如果玩家少於 5 個,它將包括套接字消息中除最后一個之外的所有玩家。 例如,如果有 3 個玩家,在完成 player3 變量賦值之前,它似乎正在運行 player4 else 語句(當為空白時)。 我已經嘗試對其進行研究並發現了 promises 和 async/await,但我對它的理解不足以使其適用於我的情況,或者它是否適用。 這是很多嵌套的 if 語句。 我覺得循環會更好,但不確定如何正確執行。 非常感謝任何幫助和建議。
if (data.teamNum == 'team1') {
team1.teamNum = 'team1';
fs.access('./public/images/players/' + data.player1, function(error) {
if (error) {
console.log(data.player1 + " icons do not exist.")
team1.player1pic = "default"
} else {
console.log(data.player1 + " icons exist.")
fs.readdir('./public/images/players/' + data.player1, (error, files) => {
team1.player1pic = files; // return the number of files
console.log(data.player1 + " has " + team1.player1pic + " pics.");
});
}
if (data.player2 != 'blank') {
fs.access("./public/images/players/" + data.player2, function(error) {
if (error) {
console.log(data.player2 + " icons do not exist.")
team1.player2pic = "default"
} else {
console.log(data.player2 + " icons exist.")
fs.readdir('./public/images/players/' + data.player2, (error, files) => {
team1.player2pic = files; // return the number of files
console.log(data.player2 + " has " + team1.player2pic + " pics.");
});
}
if (data.player3 != 'blank') {
fs.access("./public/images/players/" + data.player3, function(error) {
if (error) {
console.log(data.player3 + " icons do not exist.")
team1.player3pic = "default"
} else {
console.log(data.player3 + " icons exist.")
fs.readdir('./public/images/players/' + data.player3, (error, files) => {
team1.player3pic = files; // return the number of files
console.log(data.player3 + " has " + team1.player3pic + " pics.");
});
}
if (data.player4 != 'blank') {
fs.access("./public/images/players/" + data.player4, function(error) {
if (error) {
console.log(data.player4 + " icons do not exist.")
team1.player4pic = "default"
} else {
console.log(data.player4 + " icons exist.")
fs.readdir('./public/images/players/' + data.player4, (error, files) => {
team1.player4pic = files; // return the number of files
console.log(data.player4 + " has " + team1.player4pic + " pics.");
});
}
if (data.player5 != 'blank') {
fs.access("./public/images/players/" + data.player5, function(error) {
if (error) {
console.log(data.player5 + " icons do not exist.")
team1.player5pic = "default"
} else {
console.log(data.player5 + " icons exist.")
fs.readdir('./public/images/players/' + data.player5, (error, files) => {
team1.player5pic = files; // return the number of files
console.log(data.player5 + " has " + team1.player5pic + " pics.");
console.log('sending pics');
feud.in(data.room).emit('teampics', team1);
});
}
});
} else {
console.log('sending pics');
feud.in(data.room).emit('teampics', team1);
}
});
} else {
console.log('sending pics');
feud.in(data.room).emit('teampics', team1);
}
});
} else {
console.log('sending pics');
feud.in(data.room).emit('teampics', team1);
}
});
} else {
console.log('sending pics');
feud.in(data.room).emit('teampics', team1);
}
});
}
我希望代碼是不言自明的。 我還沒有測試過getPlayerPic
function。 我使用callback('default')
進行測試。
如果您必須編寫相同的代碼兩次以上,請始終將其設為 function,您可以多次運行該代碼。 代碼將更容易閱讀,也更容易找到問題。
// function to get the player picture
function getPlayerPic(player, callback) {
//return callback('default' + player);
fs.access('./public/images/players/' + player, function(error) {
if (error) return callback('default');
fs.readdir('./public/images/players/' + data.player1, (error, files) => {
callback(files);
});
});
};
// test data
var data = {
teamNum: 'team1',
player1: 'p1',
player2: 'p2',
player3: 'p3',
player4: 'blank',
player5: 'blank',
}
var team1 = {};
if (data.teamNum == 'team1') {
team1.teamNum = 'team1';
var players = Object.keys(data).filter(p => p.startsWith('player')).reverse();
// players = [ 'player1', 'player2', 'player3', 'player4', 'player5' ];
function next(callback) {
var p = players.pop(); // pop an item from players
console.log('p', p);
if (p && data[p] && data[p] !== 'blank') // if it exists and is not blank
getPlayerPic(data[p], function(pic){
team1[p + 'pic'] = pic;
next(callback);
});
else // we are done here
callback();
};
next(function(){
console.log('sending pics', team1);
/*
sending pics { teamNum: 'team1',
player1pic: 'defaultp1',
player2pic: 'defaultp2',
player3pic: 'defaultp3' }
*/
});
}
這是解決同一問題的更實用的方法。
(如果您迷上了函數式編程,請查看JS Allongé 。)
警告 rogantis:此代碼完全未經測試,我敢打賭它需要調試。 我沒有研究fs.access
和fs.addredir
是如何工作的,所以它可能還需要重構以使回調合法。
const { teamNum, room, player1, player2, player3, player4, player5 } = data;
const playersList = [player1, player2, player3, player4, player5];
let done;
// We're only dealing with team1 for now
const team1 = {};
let team = team1;
team.teamNum = teamNum;
// Assigns icons for each player (stops if a blank player is found)
for(let player of playersList){
assignIcons(player);
if(isLastPlayer(player)){
break;
}
}
// Primary functions
function assignIcons(player){
fs.access(getPath(player), accessCallback(error, player));
}
function accessCallback(error, player){
if (error) {
// Logs "player has no icons" and assigns default
logPlayerHasIcons(player, false);
assignIconCount(player, "default");
}
else {
// Logs "player has icons" and gets the count
logPlayerHasIcons(player, true);
fs.readdir(getPath(player), readdirCallback(error, fileCount, player);
}
}
function readdirCallback(error, fileCount, player){
// Assigns the icon count for this player
if(error){ console.log(error); }
assignIconCount(player, fileCount);
logIconCount(getPlayerNum(player), fileCount);
// Emits pics if done
if(isLastPlayer(player)){
emitPics();
}
}
function emitPics(){
console.log('sending pics');
feud.in(room).emit('teampics', team);
}
function assignIconCount(player, val){
const
playerNum = getPlayerNum(player),
playerPicPropName = `player${playerNum}pic`;
team[playerPicPropName] = val;
}
// Supporting functions
function isLastPlayer(player){
const playerNum = getPlayerNum();
return (
(playerNum == 5) ||
(playersList[playerNum] == "blank") // playerNum = index of next player
);
}
function getPlayerNum(player){
return playersList.indexOf(player) + 1;
}
function getPath(player){
return "./public/images/players/" + player;
}
function logPlayerHasIcons(player, doesHaveIcons){
console.log(`${player} ${(doesHaveIcons ? "has" : "has no")} icons`);
}
function logIconCount(playerNum, count){
console.log(`player${playerNum} has ${count} pics`);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.