异步行为中的节点js丢失:未定义 [英] Node js lost in asynchronous behaviour: undefined
问题描述
目标
免责声明:我是节点世界的新手,并且围绕节点异步行为进行艰难的时间包装。 b $ b
我试图编写一个包装函数来在给定的url上执行 https.get
,然后
代码>
const https = require('https');
//获取用户详细信息
var myUrl =< valid-url> ;;
$ b $ const getJson = function(url){
// https获取请求
const req = https.get(url,(res)=> {
/ /获得状态码
const {statusCode} = res;
const contentType = res.headers ['content-type'];
//检查错误
let error;
if(statusCode!== 200){
error = new Error('Request Failed.\\\
'+
`Status Code:$ {statusCode}`) ;
} else if(!/ ^ application \ / json / .test(contentType)){
error = new错误('Invalid content-type.\\\
'+
`如果(错误){
console.error(error.message);
//将响应数据消耗到了$ {contentType}`);
}
释放内存
res.resume();
return;
}
//解析json
res.setEncoding('utf8');
let rawData ='';
res.on('data',(chunk) => {rawData + = chunk;});
res.on('end',()=> {
try {
const parsedData = JSON.parse(rawData);
console.log(parsedData);
} catch(e){
console.error(e.message);
}
}); ('error',(e)=> {
console.error(`Got error:$ {e.message}`);
});
}
console.log(getJson(myUrl));
输出
undefined
{user_id:< user-id> ;,
name:'Ajay Krishna Teja',
email:< my-email> }
Issue
c $ c> https.get 能够达到终点并获取数据但无法返回json。不断返回未定义
。
我试过的东西
- 在
res.on(end)
块中返回parsedData
- 定义
var
并复制parsedData
- 复制到全局变量(尽管我知道这是非常糟糕的做法)
我抬头的地方
< ol>
<> >
更新:工作代码
c onst getJson = function(url,callback){
// https获取请求
const req = https.get(url,(res)=> {
//获取状态码
const {statusCode} = res;
const contentType = res.headers ['content-type'];
//检查错误
让错误;
if(statusCode!== 200){
error = new Error('Request Failed.\\\
'+
`Status Code:$ {statusCode}`);
} else if(!/ ^ application \ / json / .test(contentType)){
error = new错误('Invalid content-type.\\\
'+
`Expected application / json,但收到$ {contentType}`);
}
if(error){
console.error(error.message);
//消耗响应数据以释放内存
res.resume();
return;
}
//解析json
res.setEncoding('utf8');
let rawData ='';
res.on('data',(chunk)=> {rawData + = chunk;});
res.on('end',()=> {
try {
const parsedData = JSON.parse(rawData);
callback(parsedData);
)catch(e){
callback(false);
console.error(e.message);
}
}); ('error',(e)=> {
console.error(`Got error:$ {e.message}`);
});
return req;
}
//调用
getJson(amznProfileURL,(res)=> {
console.log(res);
});
简短回答:您不会在getJson中返回任何内容函数和 undefined
是默认的Node / Javascript返回值。
函数getJson(){
callAsyncFunction(param1,param2,param3)
//没有返回值!
}
更长的回答:Javascript(和Node作为结果)是单线程语言它使用回调函数作为将异步结果返回给被调用者的机制。为此,您需要将一个函数作为参数传递给异步函数,然后只要异步函数准备好发送它的结果,就会在将来的某个时刻调用该函数。从这个匿名函数调用 return
实际上只是从您发送到异步函数的回调函数中返回。
函数getJson(){
console.log('A')
//开始请求,但getJson继续执行!
在我被调用的时候,'B'已经被打印出来并且函数已经存在了,
http.get(url,(res)=> {
console.log('C')返回!
返回true //这将不会返回getJson!它只会返回不做任何事情的回调函数!
})
console.log('B')
//函数的结尾没有返回值,返回undefined!
}
//将打印'A','B','C'
有几种不同的方法可以处理这个问题。回调传统上被使用,但Javascript本身也支持 Promises ,它们更容易管理,并且在默认情况下在许多流行的框架中使用。
您可以通过提供自己的回调参数来调用回调函数,只要 http.get
返回本身。
//定义第二个回调参数的getJson $ b $ const getJson = function(url,callback){
http.get(url,(res)=> {
if(res){
callback(res)//结果回来了,发送到你自己的回调函数
} else {
callback(false)//请求失败,发回false表示失败
}
})
}
//现在我可以使用getJson并获得结果!
getJson('http://getjson.com',(res)=> {
console.log('got result!',res)
})
Objective
Disclaimer: I am new to node world and having tough time wrapping head around node asynchronous behaviour.
I am trying to write a wrapper function to do a https.get
on a given url and return json
output.
Code
const https = require('https');
// Get the user details
var myUrl = <valid-url>;
const getJson = function(url) {
// https get request
const req = https.get(url, (res) => {
// get the status code
const { statusCode } = res;
const contentType = res.headers['content-type'];
// check for the errors
let error;
if (statusCode !== 200) {
error = new Error('Request Failed.\n' +
`Status Code: ${statusCode}`);
} else if (!/^application\/json/.test(contentType)) {
error = new Error('Invalid content-type.\n' +
`Expected application/json but received ${contentType}`);
}
if (error) {
console.error(error.message);
// consume response data to free up memory
res.resume();
return;
}
//parse json
res.setEncoding('utf8');
let rawData = '';
res.on('data', (chunk) => { rawData += chunk; });
res.on('end', () => {
try {
const parsedData = JSON.parse(rawData);
console.log(parsedData);
} catch (e) {
console.error(e.message);
}
});
}).on('error', (e) => {
console.error(`Got error: ${e.message}`);
});
}
console.log(getJson(myUrl));
Output
undefined
{ user_id: <user-id>,
name: 'Ajay Krishna Teja',
email: <my-email> }
Issue
So the https.get
is able to hit end point and get data but not able to return the json. Constantly returning Undefined
.
Things I tried
- Returning
parsedData
onres.on(end)
block - Defining a
var
and copyingparsedData
- Copying to a global variable (although I knew it's very bad practice)
Places I looked up
- Node.js variable declaration and scope
- How to get data out of a Node.js http get request
- Javascript function returning undefined value in node js
Updated: Working code
const getJson = function(url,callback) {
// https get request
const req = https.get(url, (res) => {
// get the status code
const { statusCode } = res;
const contentType = res.headers['content-type'];
// check for the errors
let error;
if (statusCode !== 200) {
error = new Error('Request Failed.\n' +
`Status Code: ${statusCode}`);
} else if (!/^application\/json/.test(contentType)) {
error = new Error('Invalid content-type.\n' +
`Expected application/json but received ${contentType}`);
}
if (error) {
console.error(error.message);
// consume response data to free up memory
res.resume();
return;
}
//parse json
res.setEncoding('utf8');
let rawData = '';
res.on('data', (chunk) => { rawData += chunk; });
res.on('end', () => {
try {
const parsedData = JSON.parse(rawData);
callback(parsedData);
} catch (e) {
callback(false);
console.error(e.message);
}
});
}).on('error', (e) => {
console.error(`Got error: ${e.message}`);
});
return req;
}
// calling
getJson(amznProfileURL,(res) => {
console.log(res);
});
Short answer: You are not returning anything in your getJson function and undefined
is the default Node/Javascript return value.
function getJson(){
callAsyncFunction(param1, param2, param3)
// there is no return value!
}
Longer answer: Javascript (and Node as a result) is a single threaded language that uses callbacks as it's mechanism to return async results back to the callee. To do this, you pass a function into asynchronous functions as a parameter and then that function gets called at some point in the future whenever the asynchronous function is ready to send back it's result. Calling return
from this "anonymous function" is actually just returning from the "callback" function you are sending into the async function.
function getJson(){
console.log('A')
// request is started, but getJson continues execution!
http.get(url, (res)=> {
console.log('C') // by the time I'm called, 'B' has already been printed and the function has returned!
return true // this won't return getJson! It will only return the callback function which doesn't do anything!
})
console.log('B')
// end of function without return value, return undefined!
}
// Will print 'A', 'B', 'C'
There are a couple different ways you can handle this. Callbacks have been used traditionally but Javascript also natively supports Promises which are a little easier to manage and are used in many popular frameworks by default.
You can implement your function with callbacks by providing your own callback parameter to call as soon as http.get
returns itself.
// define getJson with second callback parameter
const getJson = function(url, callback) {
http.get(url, (res) => {
if(res){
callback(res) // result came back, send to your own callback function
} else {
callback(false) // request failed, send back false to signify failure
}
})
}
// now I can use getJson and get the result!
getJson('http://getjson.com', (res) => {
console.log('got result!', res)
})
这篇关于异步行为中的节点js丢失:未定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!