簡體   English   中英

Javascript 使用 if 語句時的執行順序

[英]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.accessfs.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM