将服务器端的“数据”传递给客户端后,我无法将“数据”存储到变量中并收到未定义的信息。
为什么会这样?我该如何解决?
请求是在客户端进行的:
(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);
})
});
答案 0 :(得分:0)
您应该尝试在.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)
}
答案 1 :(得分:0)
这里的问题是fetch
调用是 async ,这意味着您实际上不确定要何时完成。相反,如果您需要依赖于调用fetch
的结果的任何数据,则必须将其链接到回调。
您可以这样考虑:
我告诉我的朋友去fetch
的URL,但是我没有等到他完成后,而是给他指示(回调)完成后的操作,然后我可以做一些事情与此同时。这些说明还包含对变量M
的访问权限,变量完成后他将对其进行更新。
我不知道他什么时候才能完成,所以我不能依赖M
的值作为要执行的任何操作所获取的数据。因此,如果我要依赖于所获取的数据,则必须将其包含在说明中。
解决方法是将另一个回调附加到Promise链上。您可以按照函数式编程的方式进行操作:
fetch(url)
.then((response) => response.json())
.then(filter)
.then(process);
function filter(data) {
console.log('data :', data) // 25
M = JSON.stringify(data);
}
function process(data) {
...
}
您可以在此处阅读有关Promise链的更多信息:
注意:对于严重异步代码使用全局变量通常不是一个好主意。您已经了解了原因;很难知道何时将变量设置为什么值,因为无法保证异步函数的执行顺序。更好的方法是传递需要使用的数据,就像我上面对process(data)
所做的那样。之所以称为pure
函数,是因为没有触及该函数外部的变量,它所做的只是获取输入参数并将其转换为返回值。