数据从服务器传递到客户端后如何存储变量?
How store variable after data has been passed from server to client?
将我的服务器端 'data' 传递给客户端后,我无法将 'data' 存储到变量中并收到未定义的。
为什么会发生这种情况,我该如何解决?
客户端发出请求:
(function () {
var M;
var url = '/app/get/metafield';
fetch(url)
.then((response) => response.json())
.then(function (data) {
filter(data)
});
function filter(data) {
console.log('data :', data) // 25
M = JSON.stringify(data);
}
console.log('M :', M) // undefined
});
这是服务器端代码:
app.get('/app/get/metafield', function (req, res, next) {
function (error, response, body) {
var data = JSON.parse(body)
var M = data.metafields[0].value;
return res.json(M);
})
});
您应该尝试 运行 .then()
块中的 console.log。这是因为 http 请求是异步操作,因此在您上面的代码块中,带有 console.log('M :', M)
的行将在请求完成并返回之前执行。
因此,您应该在您定义的过滤器函数中添加 console.log()
语句,这样 console.log()
将在承诺完成后执行。
fetch(url)
.then((response) => response.json())
.then(function (data) {
filter(data);
console.log(data);
});
function filter(data) {
console.log('data :', data) // 25
M = JSON.stringify(data);
console.log('M :', M)
}
这里的问题是 fetch
调用是 async,这意味着您无法确定它何时会完成。相反,如果您想要任何依赖于调用 fetch
结果的数据,则必须将其链接到回调。
你可以这样想:
我告诉我的朋友去 fetch
a URL,但我没有等到他完成,而是给了他指示(回调),告诉他在他完成时该怎么做完成,然后我可以同时处理其他事情。该说明还包含对变量 M
的访问权限,他将在完成后更新该变量。
我不知道他什么时候结束,所以我不能依赖 M
的值作为我想做的任何事情的获取数据。因此,如果我想要一些依赖于获取的数据的东西,我必须将其包含在说明中。
补救措施是将另一个回调附加到 Promise 链。您可以使用 functional-programming 样式来执行此操作:
fetch(url)
.then((response) => response.json())
.then(filter)
.then(process);
function filter(data) {
console.log('data :', data) // 25
return JSON.stringify(data);
}
function process(data) {
...
}
您可以在此处阅读有关 Promise 链的更多信息:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises#Chaining
- https://javascript.info/promise-chaining
注意:将全局变量用于大量异步代码通常不是一个好主意。你已经意识到原因了;很难知道何时将变量设置为什么值,因为无法保证异步函数的执行顺序。更好的方法是传递你需要使用的数据,就像我上面用 process(data)
所做的那样。这被称为 pure
函数,因为没有触及函数外部的变量,它所做的只是获取输入参数并将其转换为 returns 值。
将我的服务器端 'data' 传递给客户端后,我无法将 'data' 存储到变量中并收到未定义的。
为什么会发生这种情况,我该如何解决?
客户端发出请求:
(function () {
var M;
var url = '/app/get/metafield';
fetch(url)
.then((response) => response.json())
.then(function (data) {
filter(data)
});
function filter(data) {
console.log('data :', data) // 25
M = JSON.stringify(data);
}
console.log('M :', M) // undefined
});
这是服务器端代码:
app.get('/app/get/metafield', function (req, res, next) {
function (error, response, body) {
var data = JSON.parse(body)
var M = data.metafields[0].value;
return res.json(M);
})
});
您应该尝试 运行 .then()
块中的 console.log。这是因为 http 请求是异步操作,因此在您上面的代码块中,带有 console.log('M :', M)
的行将在请求完成并返回之前执行。
因此,您应该在您定义的过滤器函数中添加 console.log()
语句,这样 console.log()
将在承诺完成后执行。
fetch(url)
.then((response) => response.json())
.then(function (data) {
filter(data);
console.log(data);
});
function filter(data) {
console.log('data :', data) // 25
M = JSON.stringify(data);
console.log('M :', M)
}
这里的问题是 fetch
调用是 async,这意味着您无法确定它何时会完成。相反,如果您想要任何依赖于调用 fetch
结果的数据,则必须将其链接到回调。
你可以这样想:
我告诉我的朋友去
fetch
a URL,但我没有等到他完成,而是给了他指示(回调),告诉他在他完成时该怎么做完成,然后我可以同时处理其他事情。该说明还包含对变量M
的访问权限,他将在完成后更新该变量。我不知道他什么时候结束,所以我不能依赖
M
的值作为我想做的任何事情的获取数据。因此,如果我想要一些依赖于获取的数据的东西,我必须将其包含在说明中。
补救措施是将另一个回调附加到 Promise 链。您可以使用 functional-programming 样式来执行此操作:
fetch(url)
.then((response) => response.json())
.then(filter)
.then(process);
function filter(data) {
console.log('data :', data) // 25
return JSON.stringify(data);
}
function process(data) {
...
}
您可以在此处阅读有关 Promise 链的更多信息:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises#Chaining
- https://javascript.info/promise-chaining
注意:将全局变量用于大量异步代码通常不是一个好主意。你已经意识到原因了;很难知道何时将变量设置为什么值,因为无法保证异步函数的执行顺序。更好的方法是传递你需要使用的数据,就像我上面用 process(data)
所做的那样。这被称为 pure
函数,因为没有触及函数外部的变量,它所做的只是获取输入参数并将其转换为 returns 值。