Javascript NodeJS中异步URL解析的处理

Javascript NodeJS中异步URL解析的处理,javascript,node.js,asynchronous,callback,Javascript,Node.js,Asynchronous,Callback,我对Node.js和Javascript还很陌生,所以请原谅我对回调机制Bacchanalia的混淆 我的问题 我正在构建一个简单的Node.js应用程序,它接收HTTP请求,并将JSON正文负载和URL参数作为输入发送给函数。为了学习,我不使用任何外部框架或npm包 所以基本上 curl -i \ -H "Content-Type: application/json" \ -X POST \ -d '{"jsonKey":"jsonValue"}' \

我对Node.js和Javascript还很陌生,所以请原谅我对回调机制Bacchanalia的混淆

我的问题 我正在构建一个简单的Node.js应用程序,它接收HTTP请求,并将JSON正文负载和URL参数作为输入发送给函数。为了学习,我不使用任何外部框架或
npm

所以基本上

curl -i \
     -H "Content-Type: application/json" \
     -X POST \
     -d '{"jsonKey":"jsonValue"}' \
     'http://localhost:8888/y?urlKey=urlValue'
应该使用参数
f({“jsonKey”:“jsonValue”,“urlKey”:“urlValue”})调用任意函数
f

转换URL参数非常简单,根本不需要回调:

/* Parse the URL arguments */
function parseArguments(request) {
    var url_obj = url.parse(request.url, true);
    return url_obj.query;
}
当我尝试将JSON负载添加到返回值时,图变厚:

/* Parse the URL arguments and the JSON payload */
function parseArguments(request) {
    // URL Parameters 
    var arguments_as_object = url.parse(request.url, true).query;

    // JSON Payload, if any
    var body = [];
    request.on('data', function(chunk) {
        body.push(chunk);
    }).on('end', function() {
        body = Buffer.concat(body).toString();
        if (body) {
            body = JSON.parse(body);
            Object.assign(arguments_as_object, body);
        }
        console.log(new Date(), "Arguments with JSON are ", arguments_as_object);
    });

    console.log(new Date(), "Return value is ", arguments_as_object);
    return arguments_as_object;
}
记录如下:

2017-04-16T13:14:47.807Z 'Return value is ' { a: 'b' }
2017-04-16T13:14:47.826Z 'Arguments with JSON are ' { a: 'b', jsonKey: 'jsonValue' }
毫不奇怪,
parseArguments
由于javascript的异步特性,在JSON解析完成之前返回

我的问题 如何获取异步调用的结果并在函数外部使用它们?除了发送包含所有参数的回调函数,还有其他方法吗?

我试过什么
  • SFTW
  • 。这似乎是正确的方法,但是我必须将回调的所有参数发送到
    parseArguments
    ,这将在其签名中添加许多不必要的变量

    • 我想你或多或少回答了你自己的问题。您必须使用回调而不是返回值

      通过将该函数包装到另一个函数中,您可以在某种程度上解决将所有回调参数发送到parseArguments的问题:

      function mainFunc = (a, b, c, jsonData) {
      ...
      }    
      function parseCb = (jsonData) {
      mainFunc(1,2,3, jsonData)
      }
      parseArguments(request, parseCb)
      
      您还可以通过实现承诺来为异步代码注入一定程度的清晰性,这些承诺可以像同步变量一样返回和传递:

      function parseArguments(request) {
      
      return new Promise((resolve, reject) => {
          // URL Parameters 
          var arguments_as_object = url.parse(request.url, true).query;
      
          // JSON Payload, if any
          var body = [];
          request.on('data', function(chunk) {
              body.push(chunk);
          }).on('end', function() {
              body = Buffer.concat(body).toString();
              if (body) {
                  body = JSON.parse(body);
                  Object.assign(arguments_as_object, body);
                 resolve(arguments_as_object)
              }
              console.log(new Date(), "Arguments with JSON are ", arguments_as_object);
          });
      
          console.log(new Date(), "Return value is ", arguments_as_object);
          return arguments_as_object;
      }
      })
      

      你不能。异步操作在函数返回之前不会完成,因此无法从函数返回异步结果。您必须使用回调或承诺。有关各种选择,请参见。我建议您从函数中返回一个承诺,然后调用方可以对该承诺使用
      .then()
      ,以获得异步结果。