【问题标题】:using ajax context does not resolve scope issue使用 ajax 上下文不能解决范围问题
【发布时间】:2018-05-31 08:39:47
【问题描述】:

我无法使 ajax 上下文工作:-

var msgdata = "";
$.ajax({
  type: "POST",
  url: "players/" + joinplayer + "/joingame.php",
  data: { 
    userID: "<?php echo $_SESSION['username']; ?>",
    gameinfo: JSON.stringify(<?php echo json_encode($_SESSION['profile']['user'], true); ?>)
  },
  context: msgdata,
  success: function(data) {
    msgdata = data;
    $.ajax({
      type: "POST",
      url: "renamejoin.php",
      data: { 
        userID: "<?php echo $_SESSION['username']; ?>",
        joinID: joinplayer
      },
      context: msgdata,
      success: function(data) {
        if (data == "" && msgdata != "") {
          // sucessfully joined a player's game
        } else {
            alert(data);
        }
      },
      error: function() {   
        alert(joinplayer + "'s game is no longer available.");
      }
    });
  },
  error: function() {
    alert(joinplayer + "'s game is no longer available.");
  }
});
if (msgdata == "");
  // start showing games awaiting players again
  gamefeedrefresh;
  timer = window.setInterval(gamefeedrefresh, 2500);
}

msgdata 在这个最后的 if 语句中始终是 ""。问题似乎是范围问题,但即使是其中一个或两个上下文语句都没有区别。

是否可以解决此范围问题?感谢所有建议。

【问题讨论】:

  • context 必须是一个 OBJECT,而不是一个原语 - 见 documentation

标签: javascript php jquery ajax scope


【解决方案1】:

考虑到异步性后,整体解决方案并不太复杂。

主要问题是为错误退出创建一个函数 然后等待触发第二次成功 使用第一个 ajax 调用中的 msgdata, 始终在范围内,但仅有效 在第二个 ajax 成功触发时。

joinfailed 函数可以是内联的,因此 joinplayer 仍然在作用域内,但我无法决定将它放在哪个错误出口上,所以我决定将它分开。

$("#gamefeed").on('click', ".chooseGame", function (evnt) {
  $.ajax({
    type: "POST",
    url: "players/" + joinplayer + "/joingame.php",
    data: { 
      userID: "<?php echo $_SESSION['username']; ?>",
      gameinfo: JSON.stringify(<?php echo json_encode($_SESSION['profile']['user'], true); ?>)
    },
    success: function(data) {
      msgdata = data;
      $.ajax({
        type: "POST",
        url: "renamejoin.php",
        data: { 
          userID: "<?php echo $_SESSION['username']; ?>",
          joinID: joinplayer
        },
        success: function(data) {
          if (data != "") {
            joinfailed(joinplayer);
          } else {
            alert(msgdata); // "you joined joinplayer's game"
            // initialise comms and join the game
          }
        },
        error: function() {   
          joinfailed(joinplayer);
        }
      });
    },
    error: function() {
      joinfailed(joinplayer);
    }
  });
});
function joinfailed(joinplayer) {
  alert(joinplayer + "'s game is no longer available.");
  // start showing games awaiting players again
  gamefeedrefresh;
  timer = window.setInterval(gamefeedrefresh, 2500);
}

【讨论】:

    【解决方案2】:

    如果您想强制浏览器在继续阅读脚本之前先完成请求,您只需在您的 ajax 方法中添加async 选项并将其设置为false

    async: false
    

    【讨论】:

    • 不推荐使用主线程上的同步 xm​​lhttprequests 的坏建议:p
    • 也许对临时解决方案有用,而我想出正确的异步方法。这也有助于了解异步版本需要什么。
    • 我无法让async: false 在这种情况下工作:-(
    【解决方案3】:

    Ajax 请求是异步的,这意味着程序的其余部分将在请求返回之前执行。如果您想在请求完成后运行代码,请将其移至 success 函数体中。

    您可能还想看看Promise

    【讨论】:

    • 好点。我明天会检查他们,因为我今天有危机:-(
    猜你喜欢
    • 2016-12-04
    • 1970-01-01
    • 1970-01-01
    • 2017-07-29
    • 1970-01-01
    • 2021-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多