异步行为中的节点js丢失:未定义 [英] Node js lost in asynchronous behaviour: undefined

查看:201
本文介绍了异步行为中的节点js丢失:未定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目标




免责声明:我是节点世界的新手,并且围绕节点异步行为进行艰难的时间包装。 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。不断返回未定义



我试过的东西




  1. res.on(end)块中返回 parsedData
  2. 定义 var 并复制 parsedData

  3. 复制到全局变量(尽管我知道这是非常糟糕的做法)



我抬头的地方



< ol>
<> >
  • 如何从Node.js http获取请求中获取数据 Javascript函数返回节点js中未定义的值



  • 更新:工作代码



      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

    1. Returning parsedData on res.on(end) block
    2. Defining a var and copying parsedData
    3. Copying to a global variable (although I knew it's very bad practice)

    Places I looked up

    1. Node.js variable declaration and scope
    2. How to get data out of a Node.js http get request
    3. 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屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆