【问题标题】:Handling asynchronous URL parsing in NodeJS [duplicate]在 NodeJS 中处理异步 URL 解析
【发布时间】:2017-09-12 06:14:27
【问题描述】:

我对 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 args 非常简单,根本不需要回调:

/* Parse the URL arguments */
function parseArguments(request) {
    var url_obj = url.parse(request.url, true);
    return url_obj.query;
}

当我尝试将 JSON Payload 添加到返回值时,情节变厚了:

/* 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' }

不出所料,由于 javascript 的异步特性,parseArguments 在 JSON 解析完成之前返回

我的问题

如何获取异步调用的结果并在函数外使用?除了发送带有所有参数的回调函数之外,还有其他方法吗?

我尝试了什么

【问题讨论】:

  • 你不能。在您的函数返回之前,异步操作不会完成,因此无法从您的函数返回异步结果。您将不得不使用回调或承诺。有关各种选择,请参阅marked duplicate。我建议从你的函数返回一个承诺,然后调用者可以在承诺上使用.then() 来获得异步结果。

标签: javascript node.js asynchronous callback


【解决方案1】:

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

您可以通过将该函数包装在另一个函数中来解决您对将所有回调参数发送到 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;
}
})

【讨论】:

    猜你喜欢
    • 2019-10-01
    • 2022-01-12
    • 2014-08-05
    • 1970-01-01
    • 2013-03-19
    • 1970-01-01
    • 2011-08-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多