Javascript 快速路由和异步代码-如何发送异步代码的结果?

Javascript 快速路由和异步代码-如何发送异步代码的结果?,javascript,ajax,node.js,asynchronous,Javascript,Ajax,Node.js,Asynchronous,我想要实现的目标的简单概述: 对服务器上的特定URL进行AJAX调用 Express Routes(在“app.js”中)然后运行“Send.js”中的Node.js代码 “Send.js”的输出被用作“res.Send”方法对AJAX请求的响应 我的问题是“Send.js”使用异步方法,因此在发送响应时,我试图在“res.Send(response)”中返回的“response”变量没有定义,因为“Send.js”中的“sendOn”函数自然会在异步代码完成之前完成 我知道使用回调可能是这里

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

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

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

    我知道使用回调可能是这里的解决方案,因此在定义响应之前不会调用“res.send(response)”,我不知道如何实现这一点,因为这里有两个不同的文件:

    app.js(简化):

    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;
    
    我只是不知道如何处理这么多异步回调


    最后一点注意:我既不要求也不期望任何人为我这样做,但我希望你能为我指明正确的方向,提前谢谢。

    从我的观点和几天前我所学到的,只要在sendMessage函数中添加你想对res对象做的任何事情就行了(如果可能的话)。由于使用了javascript,因此应该可以从那里访问res对象


    关于回调和callbackhell的更多提示:

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


    有关回调和callbackhell的进一步提示:

    返回值的唯一方法是通过回调。这是真的,即使你使用承诺

    回调是返回值的方式。因此,由于
    sendOn()
    需要返回一个值,它需要接受回调(或者返回一个承诺,承诺将接受回调)

    基本上,
    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()

    一直向下传递的回调。返回值的唯一方法是通过回调。这是真的,即使你使用承诺

    回调是返回值的方式。因此,由于
    sendOn()
    需要返回一个值,它需要接受回调(或者返回一个承诺,承诺将接受回调)

    基本上,
    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()

    一直向下传递的回调,我的建议是使用它来处理异步调用,您将能够执行类似于
    send.sendOn()的操作。然后(函数(响应){res.send(响应);})
    我建议使用
    async
    模块来避免这个问题
    https://github.com/caolan/async
    我的建议是使用它来处理异步调用,您将能够执行类似的操作
    send.sendOn().then(函数(响应){res.send(响应);})
    我建议使用
    async
    模块来避免这个问题
    https://github.com/caolan/async
    谢谢你的链接谢谢你的链接太棒了,谢谢你如此清晰地简化和解释!那太棒了,谢谢你如此清晰的解释和简化!