我最近选择了Node,看到事情并不总是按顺序运行。因为我习惯了,我很困惑
1) Assignment
2) Print data
当前我正在运行以下功能并调用var x = searchForProfessor("prof_name_here");
然后我只是调用console.log(x);
来获取未定义。
我一直在阅读关于网络上的回调,我无法理解这个想法并将其应用于此代码。有人可以通过回调让我有一些直觉来实现上述目标吗?
var searchForProfessor = function searchForProfessor(teacher_name) {
google.resultsPerPage = 10
var nextCounter = 0
google(teacher_name, function (err, res){
for (var i = 0; i < res.links.length; ++i) {
var link = res.links[i];
if (!link.title.includes('Add') || !link.title.includes('RATINGS') || !link.title.includes("Hint")) {
request(link, function(err, resp, body){
if (!err && resp.statusCode == 200) { //If no error is going to happen, then print the data
var $ = cheerio.load(body); //Grab the body of data from 'prof_link'
var overall_rating = $('.breakdown-header .grade').text(); //Get the grade rating from the following classifications text
if (overall_rating.substr(0,3)) {
teacher_results.push(prof_name);
} //End if
} //End if
}); //End request
}//End if for comparisons ||
} //End For
}); //End google function
} //End searchForProfessor
答案 0 :(得分:2)
因为google
和request
函数都是从这些函数返回的异步数据不会立即可用,这就是为什么x
var x = searchForProfessor("prof_name_here");
在您尝试登录时始终会为您提供undefined
。
要解决此问题,您可以将函数作为参数传递给其他函数,以便在数据可用时返回。
这是一个小型模型,说明您的代码发生了什么,以及如何使用回调。
async1
模仿数据库连接 - 它通过调用传递给它的函数 1秒后使用键返回一个对象,数据为 第一个论点。
function async1(name, callback) {
var obj = { tea001: { first: 'Dave', last: 'Batman' } };
setTimeout(function () {
callback(obj[name]);
}, 1000);
}
这里我们有searchForProfessor
函数,它接受名称和函数。它使用名称调用async1
,将回调作为第二个参数传递。请注意,返回的data
是来自async1
的返回对象数据。传递给searchForProfessor
的回调用于将该数据返回到...
function searchForProfessor(teacher_name, callback) {
async1(teacher_name, function (data) {
callback(data);
});
}
...此函数调用searchForProfessor
,此时您可以记录数据。
searchForProfessor('tea001', function (data) {
console.log(data);
});
您可以在演示中看到,一旦代码运行,返回的数据大约需要一秒钟才能记录到控制台。