【问题标题】:Struggling with scope [duplicate]与范围斗争[重复]
【发布时间】:2021-03-22 03:46:06
【问题描述】:

我有点困惑为什么这不起作用。我猜这是范围问题,但不完全确定。

如果我在函数内部登录,我会将值推送到 myProjectIds。但是在外面我无法弄清楚为什么在顶部声明的全局数组是空的。

感谢任何帮助!

var myProjects = [];
var myProjectIds = [];

function getProjects() {
  $.ajax({
    method: 'GET',
    url: 'http://localhost:8080/project',
    data: {
      user: userId,
    },

    // dataType: "json",
    beforeSend: function (xhr) {
      /* Authorization header */
      xhr.setRequestHeader("Authorization", "Bearer " + userToken);
    },
    success: function (response) {
      myProjects = response;
      for (var i = 0; i < myProjects.projects.length; i++) {
        myProjectIds.push(myProjects.projects[i]._id);
      }
    }
  })
}

getProjects();
console.log(myProjectIds)

【问题讨论】:

  • 这与范围无关,与异步处理有关。您只有在 successafter 内有值(一般来说,这不是调用函数后的下一行)。您需要传递回调来处理数据或使用 Promise 和/或 async/await。
  • 您不需要将response 分配给myProjects,您可以简单地循环遍历它(例如for(..; response.length..,此外,您的循环使用@987654327 会有更整洁的外观@(或.forEach()-loop)

标签: javascript arrays scope


【解决方案1】:

这是因为您的 ajax 调用是异步的 - 浏览器在运行控制台日志时仍在等待网络请求的响应。如果您想查看此行为,请将您的日志放入循环中:

var myProjects = [];
var myProjectIds = [];

function getProjects() {
  $.ajax({
    method: 'GET',
    url: 'http://localhost:8080/project',
    data: {
      user: userId,
    },

    // dataType: "json",
    beforeSend: function (xhr) {
      /* Authorization header */
      xhr.setRequestHeader("Authorization", "Bearer " + userToken);
    },
    success: function (response) {
      myProjects = response;
      for (var i = 0; i < myProjects.projects.length; i++) {
        myProjectIds.push(myProjects.projects[i]._id);
      }
    }
  })
}

getProjects();
setInterval(function() {
    // When the network call returns, this will log a non empty array
    console.log(myProjectIds)
}, 100)

如果你想让它更容易使用,你可以使用 promise 来返回调用的结果。

以下是您的代码在承诺中的示例:

function getProjects() {
  return new Promise((resolve, reject) => {
      $.ajax({
        method: 'GET',
        url: 'http://localhost:8080/project',
        data: {
          user: userId,
        },
        beforeSend: function (xhr) {
          xhr.setRequestHeader("Authorization", "Bearer " + userToken);
        },
        success: function (response) {
          // This is a cleaner way of writing the for loop
          const myProjectIds = response.projects
               .map((project) => project._id);
          resolve(myProjectIds);
        }
      })
    }
  }
}

getProjects().then((projectIds) => {
    // Do something with the result
    console.log(projectIds)
})

【讨论】:

    猜你喜欢
    • 2021-04-30
    • 1970-01-01
    • 2015-04-23
    • 1970-01-01
    • 2015-12-07
    • 2017-06-22
    • 2020-09-18
    • 2018-05-23
    • 2013-11-08
    相关资源
    最近更新 更多