【问题标题】:Express Routing and Asynchronous Code - How do I send the result of Asynchronous Code?快速路由和异步代码 - 如何发送异步代码的结果?
【发布时间】:2016-08-16 12:50:39
【问题描述】:

我要实现的目标的简单概述:

  1. 对服务器上的特定 URL 进行 AJAX 调用
  2. Express Routes(在“app.js”中)然后在“Send.js”中运行 Node.js 代码
  3. “Send.js”的输出用作对“res.send”方法的 AJAX 请求的响应。

我的问题是“Send.js”使用了异步方法,所以我试图在“res.send(response)”中返回的“response”变量在发送响应时没有定义,因为“ “Send.js”中的“sendOn”函数自然会在异步代码完成之前完成。

我知道使用回调可能是这里的解决方案,因此在定义响应之前不会调用“res.send(response)”,鉴于我有两个单独的文件在这里:

app.js(简化版):

var send = require("./Files/Other/Send.js");


    app.post('/Lamp-On', function (req, res)
    {
        var response = send.sendOn();
        res.send(response);
    });

Send.js(简体):

client.open 和 client.sendEvent 都是接受回调作为最终参数的异步方法,并且是外部 SDK 的一部分。

var sendMessage = function ()
{
    var data = "on";
    var message = new Message(data);
    message.properties.add('Turn On');
    console.log('Sending message to turn the lamp: ' + message.getData());
    client.sendEvent(message, printResultFor('Message'));
};

var connectCallback = function () {
        if (err) {
            console.error('Could not connect: ' + err.message);
        }
        else {

            console.log('Client connected');

            client.on('message', function (msg) {
                console.log('Id: ' + msg.messageId + ' Body: ' + msg.data);
                client.complete(msg, printResultFor('completed'));
                // reject and abandon follow the same pattern.
                // /!\ reject and abandon are not available with MQTT
            });

            client.on('error', function (err) {
                console.error(err.message);
            });

            client.on('disconnect', function () {
                clearInterval(sendInterval);
                client.removeAllListeners();
                client.connect(connectCallback);
            });

            // Now call the sendMessage function.
              sendMessage();
        }
};

var sendOn = function () {
    client.open(connectCallback);
    return 
};

// Helper function to print results in the console
function printResultFor(op) {
  return function printResult(err, res) {
      if (err !== null) {
          console.log(op + ' error: ' + err.toString());
          console.log(err);
      }
        if (res) {
            console.log(op + ' status: ' + res.constructor.name);
        };
  };
}

exports.sendOn = sendOn;

我就是不知道怎么处理这么多异步回调!

最后说明:我既不要求也不期望任何人为我做这件事,但我希望你能指出正确的方向,提前谢谢。

【问题讨论】:

  • 我的建议是使用Promise 来处理异步调用,您将能够执行类似send.sendOn().then(function(response) {res.send(response);}); 的操作
  • 我建议使用async模块来避免这个问题https://github.com/caolan/async

标签: javascript ajax node.js asynchronous


【解决方案1】:

返回值的唯一方法是通过回调。即使您使用了 Promise,也是如此。

回调是您返回值的方式。所以既然sendOn()需要返回一个值,它就需要接受一个回调(或者返回一个promise并且promise会接受一个回调)。

基本上app.js 看起来像这样:

app.post('/Lamp-On', function (req, res)
{
    send.sendOn(function(err,response){
        res.send(response);
    });
});

您需要习惯的一件事是不要将函数视为子例程。而是将函数视为控制结构,例如 for 或 while 或 if。你习惯写这样的代码:

if (something) {
    something_else();
}

从概念上讲,您应该不会有太多麻烦:

doIf(something,function(){
    something_else();
});

现在是有趣的部分。如何让sendOn() 接受回调?只需将该回调一直传递给“返回”结果的函数。基本上,该过程与过程编程相反,而不是将值一直返回到外部代码,而是将代码一直传递给值:

var sendOn = function (callback) {
    client.open(function(){
        connectCallback(callback); // pass the CODE down to the value
    });
};

var connectCallback = function (callback) {
    if (err) {
        callback(err);
    }
    else {
        client.on('message', function (msg) {
            console.log('Id: ' + msg.messageId + ' Body: ' + msg.data);

            callback(null, msg.data); // Now pass the value to the CODE
        });

        sendMessage();
    }
};

我假设msg.data 是结果。如果没有相应地改变它。确保将结果传递给从 sendOn() 一路向下传递的回调。

【讨论】:

  • 太棒了,感谢您如此清晰地简化和解释!
【解决方案2】:

从我的观点和几天前我刚刚学到的东西来看,它应该可以通过简单地在你的 sendMessage 函数中添加你想要对 res 对象执行的任何操作(如果可能的话)来工作。由于使用了 javascript,因此应该可以从那里访问 res-object。

有关回调和回调地狱的更多提示:http://callbackhell.com/

【讨论】:

  • 感谢您的链接
猜你喜欢
  • 2014-09-18
  • 2015-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-25
相关资源
最近更新 更多