Javascript 匿名函数中变量的作用域
我有这个函数Javascript 匿名函数中变量的作用域,javascript,function,scope,Javascript,Function,Scope,我有这个函数 function parseLink(link) { var product; request(link, function (error, response, body) { if (!error && response.statusCode == 200) { var $ = cheerio.load(body); // title var title =
function parseLink(link) {
var product;
request(link, function (error, response, body) {
if (!error && response.statusCode == 200) {
var $ = cheerio.load(body);
// title
var title = $('h1').text();
if (!title)
var title = $('title').text();
var description = $('meta[name="description"]').attr('content');
product = new Product(link.trim(), title.trim(), description.trim());
}
});
console.log(product);
return product;
}
我不明白为什么在请求调用之外执行console.log(product)时,我得到了未定义的,但在内部,我可以看到我的产品
我在javascript中学习了很多关于作用域的知识,但我不理解,因为我在top函数中定义了product。
我需要返回这个变量,以便在另一个函数中获取它,如果在内部执行返回请求,我当然有一个未定义的,所以我需要在外部执行该操作。。。
谢谢javascript不会运行类似于
c
或php
的代码,在这些代码中,您可以确保在上一行代码准备就绪时运行下一行代码。在您的例子中,request
是一个异步函数,因此这两行
console.log(product);
return product;
通常在请求
功能准备就绪之前运行。在这种情况下,您不能仅从parseLink
函数返回一些值。这里有两种可能性:
function parseLink(link, callback) {
var product;
request(link, function (error, response, body) {
if (!error && response.statusCode == 200) {
var $ = cheerio.load(body);
// title
var title = $('h1').text();
if (!title)
var title = $('title').text();
var description = $('meta[name="description"]').attr('content');
product = new Product(link.trim(), title.trim(), description.trim());
callback(product);
}
});
}
您可以像这样运行代码
parseLink('http://...', function(product) { /* do something with the product */ });
ps:回调的使用在imo中要容易得多,但在某些情况下,您可以分离作用域,例如,如果您在
for
循环中运行它,则请求是一个异步调用,因此此过程被推送到事件队列,该队列将在当前调用堆栈完成后运行console.log
打印未定义的
,因为这是未分配变量的默认值
如果需要从异步调用返回值,则必须使用回调或承诺。下面是一个使用的示例:
因为您没有在top函数和console.log()
中为变量product
赋值,所以不要等待请求函数的赋值。您的request
函数定义的位置可能重复?谢谢,但我需要返回值,如var linkParsed=parseLink(数据[0])谢谢,我从另一个函数调用parseLink。我想在这个函数中执行类似的操作:var linkParsed=parseLink(数据[0])代码>就像我写的那样,不可能直接从异步函数返回值。在我回答的最后是一个带有回调函数的示例。米格尔还提供了一个承诺人的例子,那么C呢?您可以在调用中将指向函数的指针作为参数传递,您不知道在该调用返回时函数是否已被调用。谢谢,但我需要返回值,如var linkParsed=parseLink(数据[0])代码>谢谢,但我需要返回值,如var linkParsed=parseLink(数据[0])
@Tech您需要执行同步请求,但强烈建议不要这样做
function parseLink(link) {
return new Promise((resolve, reject) => {
request(link, function(error, response, body) {
if (error) return reject(error);
if (response.statusCode !== 200) {
return reject(new Error('Not OK'));
}
var $ = cheerio.load(body);
var title = $('h1').text() || $('title').text();
var description = $('meta[name="description"]').attr('content');
var product = new Product(link.trim(), title.trim(), description.trim());
resolve(product);
});
});
}
parseLink('http://example.com')
.then(product => {
console.log(product);
})
.catch(error => {
console.error(error);
});