我有此代码:
const request = require('request');
let url = "https://api.warframe.market/v1/items";
let options = {json: true};
let item_urls;
request(url, options, (error, res, body) => {
if (error) {
return console.log(error)
}
if (!error && res.statusCode == 200) {
console.log(body);
item_urls = body.payload.items;
}
});
console.log(item_urls);
它工作正常,并将JSON返回到变量item_urls
。
然后我尝试将自己的函数包装起来,如下所示:
const request = require('request');
let url = "https://api.warframe.market/v1/items";
let options = {json: true};
let item_urls;
function getitems(){
request(url, options, (error, res, body) => {
if (error) {
return console.log(error)
};
if (!error && res.statusCode == 200) {
console.log(body);
item_urls= body.payload.items;
};
});
};
getitems()
但是它不起作用,item_urls
最终未定义。除了包装在我的函数中之外,代码是相同的。如果您想知道为什么要将它包装在一个函数中,我需要将一个参数传递给它,但是为了简单起见并展示了这个问题,我删除了此逻辑。
谢谢,
您必须在首次获取其值的回调中使用item_urls
。您可以使用该值的唯一方法是在回调本身中或在您从那里调用的函数中使用它,然后将值传递给它。
问题是request()
是异步的并且是非阻塞的。这意味着您执行request()
,它开始操作,然后返回并继续执行更多代码(包括您尝试使用item_urls
的代码)。但是,到那时,回调尚未被调用,因此它仍然是undefined
。
最后,您知道item_urls
具有值的唯一位置是该回调内部。因此,使用该值的任何代码都必须进入该回调或在该回调内被调用。这就是在node.js中异步编程的工作方式。
因此,它需要看起来像这样:
function getitems(){
request(url, options, (error, res, body) => {
if (error) {
return console.log(error)
}
if (!error && res.statusCode == 200) {
console.log(body);
// use body.payload.items directly here
// or call some function here and pass it the value
// Do not assign it to some higher scoped variable and
// expect to use it elsewhere. Can't do that.
}
});
}
getitems()
如果要在getitems之外获取值,则需要使用回调和事件或Promise来在getitems()
之外传达异步检索到的值。您可以在此非常受欢迎的答案getitems()
中看到关于为什么不能仅从How do I return the response from an asynchronous call返回值的完整讨论。