Javascript 使用http.get-in节点理解回调
这里是新的节点程序员,由于节点的异步性质,我很难理解如何从函数返回http请求的内容。这是我的程序的精简版本。 我所要做的就是1:创建一个函数,从一个站点获取数据(如果有必要,它是JSON和XML),2:能够从程序中的任何地方调用该函数,3:能够操作从函数中返回的任何数据Javascript 使用http.get-in节点理解回调,javascript,asynchronous,callback,Javascript,Asynchronous,Callback,这里是新的节点程序员,由于节点的异步性质,我很难理解如何从函数返回http请求的内容。这是我的程序的精简版本。 我所要做的就是1:创建一个函数,从一个站点获取数据(如果有必要,它是JSON和XML),2:能够从程序中的任何地方调用该函数,3:能够操作从函数中返回的任何数据 您放置(和调用)回调函数的方式让我头疼。我已经研究了几十个http.get示例和普通回调示例,但还没有找到一个示例可以像我的示例中那样将两者合并。经过几天的失败尝试,我觉得如果有人能在我的示例中演示如何做到这一点,它可能最终
您放置(和调用)回调函数的方式让我头疼。我已经研究了几十个http.get示例和普通回调示例,但还没有找到一个示例可以像我的示例中那样将两者合并。经过几天的失败尝试,我觉得如果有人能在我的示例中演示如何做到这一点,它可能最终会在我的大脑中发出咔哒声(祈祷)。在数据有机会返回之前,您正在调用console.log()。您可以将body变量带到更高的范围并附加到该范围。即
var body;
function getwebsite(url) {
http.get(url, function (res) {
res.on('data', function (chunk) {
body += chunk;
//***Right here, I need 'body' returned out of this function***
outputBody(body);
});
});
}
var a = getwebsite('website1.com');
var b = getwebsite('website2.com');
function outputBody(val){
console.log(val);
}
这是您希望用于普通回调样式的基本模式:
function getwebsite(url, cb) {
var body = "";
http.get(url, function (res) {
res.on('data', function (chunk) {
body += chunk.toString();
// you can't return a value from this function
// the return value would be swallowed by the function
// that is calling this function
// which is not your code, but internal Node.js code
});
res.on("end", function() {
cb(null, body)
})
res.on("error" function(error) {
cb(error)
})
});
}
getwebsite("a", function(error, contentsA) {
if (error) throw "Error getting website A."
getwebsite("b", function(error, contentsB) {
if (error) throw "Error getting website B."
console.log(contentsA)
console.log(contentsB)
})
})
您可能还希望查看流控制库,如(或基于my promise的),或通用promise库,如。
不过,我建议首先熟悉回调的基本知识
对于简单的http请求,使用该模块要容易得多。那么您就不必绑定事件侦听器了。您只需要有一个函数,它可以以类似于getwebsite
函数的方式使用(它有问题!)
要熟悉异步编程,您可能需要尝试使用
fs.readFile
和fs.writeFile
读取和写入一些文件。例如,尝试将文件A的内容写入文件B。这些函数非常简单,但需要正确处理回调流。相比之下,节点的http模块相对复杂。或者使用请求模块,正如我所提到的。您想要一个延迟的(承诺也是一个延迟的)和.then()
或.when()
。js应该有文档(我不是节点开发人员,但这是Javascript中的常见模式)。编辑:谢谢你的建议。我从教程(包括您链接的教程)中了解到,Promise已从Node中删除。我不知道为什么,因为它看起来非常有用。然而,我觉得在我深入研究插件之前,我应该强迫自己理解回调(这是节点异步特性的一个重要部分);从Node.js中删除该实现是因为它没有得到很好的实现,而不是因为Node.js不“支持”延迟。这个可操作的术语留给了userland的一个练习,这意味着它将不是Node.js本机产品,但提供其功能的库仍然是可行和有用的。感谢您的建议。但问题是,我实际上不想调用console.log,我希望能够在函数之外操作数据(a和b),我只是把控制台放在那里作为一个例子,说明如何同时使用这两个变量。在您给出的示例中,假设我们替换了“console.log(body);”带有“返回体;”。什么样的语法允许它实际工作?@jwhazel,当您设计所描述的内容时(异步回调中的过程代码无法完成),您已经构建了一个(可能有限的)延迟或承诺。延迟模式或多或少地在依赖进程之间建立了一个共同的观察者,当回调返回到该对象并被观察到时,当可观察契约履行时(所有承诺履行或在设定的时间内以其他方式处理),另一个函数被调用,它合并或执行任何要求函数被观察为终止的操作。最后一行中的console.log将不起作用。也就是说,它不会记录任何内容,因为主体尚未填充。
function getwebsite(url, cb) {
var body = "";
http.get(url, function (res) {
res.on('data', function (chunk) {
body += chunk.toString();
// you can't return a value from this function
// the return value would be swallowed by the function
// that is calling this function
// which is not your code, but internal Node.js code
});
res.on("end", function() {
cb(null, body)
})
res.on("error" function(error) {
cb(error)
})
});
}
getwebsite("a", function(error, contentsA) {
if (error) throw "Error getting website A."
getwebsite("b", function(error, contentsB) {
if (error) throw "Error getting website B."
console.log(contentsA)
console.log(contentsB)
})
})