在从 API 获取数据之前使用 Javascript 中的变量
Use variables in Javascript before the data is fetched from an API
有这段javascript代码(来自神奇的CodingTrain系列!!):
我的问题如下:
我们在第 28 行将数据对象传递给 fetch-Post 请求。首先在第 17 行声明了两个变量 lat 和 lon,但没有初始化。然后它们被用于构建第 20 行中的数据对象最终传递到第 28 行中的获取函数。
我不明白的是这两个变量如何保存代码中已有的地理位置值。因为我们仅在下面的第 35-40 行中获取地理位置。这可能与异步和等待逻辑的工作方式有关,但我不确定。
01: <!DOCTYPE html>
02: <html lang="en">
03: <head>
04: <meta charset="UTF-8" />
05: <meta name="viewport" content="width=device-width, initial-scale=1.0" />
06: <meta http-equiv="X-UA-Compatible" content="ie=edge" />
07: <title>Document</title>
08: </head>
09: <body>
10: <h1>Data Selfie App</h1>
11: <p>
12: latitude: <span id="latitude"></span>°<br />
13: longitude: <span id="longitude"></span>°
14: </p>
15: <button id="submit">submit</button>
16: <script>
17: let lat, lon;
18: const button = document.getElementById('submit');
19: button.addEventListener('click', async event => {
20: const data = { lat, lon };
21: const options = {
22: method: 'POST',
23: headers: {
24: 'Content-Type': 'application/json'
25: },
26: body: JSON.stringify(data)
27: };
28: const response = await fetch('/api', options);
29: const json = await response.json();
30: console.log(json);
31: });
32:
33: if ('geolocation' in navigator) {
34: console.log('geolocation available');
35: navigator.geolocation.getCurrentPosition(async position => {
36: lat = position.coords.latitude;
37: lon = position.coords.longitude;
38: document.getElementById('latitude').textContent = lat;
39: document.getElementById('longitude').textContent = lon;
40: });
41: } else {
42: console.log('geolocation not available');
43: }
44: </script>
45: </body>
46: </html>
github 回购的 link 是这样的:https://github.com/CodingTrain/Intro-to-Data-APIs-JS
他们的教程没有解释变量和变量作用域吗?
基本上当你有这样的代码时:
let someVar;
function a() {}
const someFunc = () => someVar;
// ...
因为 a
(和 someFunc
)在他们有权访问 someVar
时被定义,他们现在保持对该变量的永久访问权。
在您的情况下,let lat, lon;
下面的所有函数声明都可以随时读取和写入这些变量。 getCurrentPosition
将 最终 将值写入这些变量,然后供 'click'
侦听器使用。如果您足够快地成功按下按钮,在 getCurrentPosition
完成之前 (或者如果 navigator
不可用)、lat
/lon
仍然是 undefined
.
另一个例子:
const funcs = [];
for (let i = 0; i < 3; i++) {
funcs.push(() => i);
}
console.log(funcs.map(f => f()));
在循环中我创建了 3 个函数(i
是 0
,1
然后是 2
)。后来我打电话给他们。即使 i
的作用域(for
-循环的主体)结束并且变量“死了”,函数仍然可以访问它们,因为它们是在变量仍然存在并且可以访问时声明的他们。另请注意,每个函数如何访问 只是 声明时处于活动状态的 i
变量,而不是 earlier/later 迭代中的 i
。
19和31之间的代码:
button.addEventListener('click', async event => {
// ...
});
... 将回调附加到事件。该回调将不会执行 now。它是将来会执行的代码,即当用户单击按钮时。
您可以将此代码块移动到第 44 行,它不会对代码逻辑有任何改变。
你可以在这个简化的代码中看到原理——一键式(点击它):
let button = document.querySelector("button");
let i = 0;
button.addEventListener("click", function () {
console.log("i =", i);
});
i = 10; // This executes first!
<button>Click me</button>
有这段javascript代码(来自神奇的CodingTrain系列!!):
我的问题如下:
我们在第 28 行将数据对象传递给 fetch-Post 请求。首先在第 17 行声明了两个变量 lat 和 lon,但没有初始化。然后它们被用于构建第 20 行中的数据对象最终传递到第 28 行中的获取函数。
我不明白的是这两个变量如何保存代码中已有的地理位置值。因为我们仅在下面的第 35-40 行中获取地理位置。这可能与异步和等待逻辑的工作方式有关,但我不确定。
01: <!DOCTYPE html>
02: <html lang="en">
03: <head>
04: <meta charset="UTF-8" />
05: <meta name="viewport" content="width=device-width, initial-scale=1.0" />
06: <meta http-equiv="X-UA-Compatible" content="ie=edge" />
07: <title>Document</title>
08: </head>
09: <body>
10: <h1>Data Selfie App</h1>
11: <p>
12: latitude: <span id="latitude"></span>°<br />
13: longitude: <span id="longitude"></span>°
14: </p>
15: <button id="submit">submit</button>
16: <script>
17: let lat, lon;
18: const button = document.getElementById('submit');
19: button.addEventListener('click', async event => {
20: const data = { lat, lon };
21: const options = {
22: method: 'POST',
23: headers: {
24: 'Content-Type': 'application/json'
25: },
26: body: JSON.stringify(data)
27: };
28: const response = await fetch('/api', options);
29: const json = await response.json();
30: console.log(json);
31: });
32:
33: if ('geolocation' in navigator) {
34: console.log('geolocation available');
35: navigator.geolocation.getCurrentPosition(async position => {
36: lat = position.coords.latitude;
37: lon = position.coords.longitude;
38: document.getElementById('latitude').textContent = lat;
39: document.getElementById('longitude').textContent = lon;
40: });
41: } else {
42: console.log('geolocation not available');
43: }
44: </script>
45: </body>
46: </html>
github 回购的 link 是这样的:https://github.com/CodingTrain/Intro-to-Data-APIs-JS
他们的教程没有解释变量和变量作用域吗?
基本上当你有这样的代码时:
let someVar;
function a() {}
const someFunc = () => someVar;
// ...
因为 a
(和 someFunc
)在他们有权访问 someVar
时被定义,他们现在保持对该变量的永久访问权。
在您的情况下,let lat, lon;
下面的所有函数声明都可以随时读取和写入这些变量。 getCurrentPosition
将 最终 将值写入这些变量,然后供 'click'
侦听器使用。如果您足够快地成功按下按钮,在 getCurrentPosition
完成之前 (或者如果 navigator
不可用)、lat
/lon
仍然是 undefined
.
另一个例子:
const funcs = [];
for (let i = 0; i < 3; i++) {
funcs.push(() => i);
}
console.log(funcs.map(f => f()));
在循环中我创建了 3 个函数(i
是 0
,1
然后是 2
)。后来我打电话给他们。即使 i
的作用域(for
-循环的主体)结束并且变量“死了”,函数仍然可以访问它们,因为它们是在变量仍然存在并且可以访问时声明的他们。另请注意,每个函数如何访问 只是 声明时处于活动状态的 i
变量,而不是 earlier/later 迭代中的 i
。
19和31之间的代码:
button.addEventListener('click', async event => {
// ...
});
... 将回调附加到事件。该回调将不会执行 now。它是将来会执行的代码,即当用户单击按钮时。
您可以将此代码块移动到第 44 行,它不会对代码逻辑有任何改变。
你可以在这个简化的代码中看到原理——一键式(点击它):
let button = document.querySelector("button");
let i = 0;
button.addEventListener("click", function () {
console.log("i =", i);
});
i = 10; // This executes first!
<button>Click me</button>