代码之家  ›  专栏  ›  技术社区  ›  sunwarr10r

Node.js Express API:如何处理多个回调

  •  0
  • sunwarr10r  · 技术社区  · 8 年前

    我有一个API端点,它执行一个函数,这个函数通过一个web套接字监听一些事件,然后通过一个API端点的回调将它的响应抛出,这样端点就可以用这个对象响应http请求。

    有时我只收到一个事件,有时我从侦听器收到两个事件。当只有第一个事件出现时,我没有问题。因为第二个事件具有优先级,所以我使用 setTimeout 等待它,以防它仍然出现。

    问题是,当第二个事件出现时,我的API端点用它的对象响应,但之后它崩溃了。我想这和第二次回调有关,我不知道怎么处理。代码的结构如下:

    app.get('/api/myendpoint', function(req, res) {
    
        myVar_1 = req.query.myvar1;
        myVar_2 = req.query.myvar2;
    
        myFunction(myVar_1, myVar_2, function(data, error) {
            if (!error) res.json(data);
            else res.json({"error": String(error)});        
        });
    
    });
    
    
    function myFunction(myVar_1, myVar_2, callback){
    
        listenOnSocket.someEvent(myVar_1,
            function(error, event) {
                if (error) callback(null, error);
                else setTimeout(function() {callback(event, null);}, 6000);
            }
        );    
    
        listenOnSocket.someEvent(myVar_2,
            function(error, event) {
                if (!error) callback(event, null); 
                else callback(null, error);
            }
        );
    
    };
    

    我的错误是这样的:

    错误[ERR\u HTTP\u HEADERS\u SENT]:发送邮件后无法设置邮件头 致客户

    1 回复  |  直到 8 年前
        1
  •  1
  •   vibhor1997a    8 年前

    为什么会这样?

    1. 1st 事件发生在您设置 timeout 对于 6000
    2. 2nd 事件发生在 6000 并且回调由于事件而执行 2
    3. 超时 完成并将挂起的函数传递给 setTimeout 执行回调,该回调将再次发送响应,并且在发送响应后无法向响应发送头。

    解决方案

    事件是否发生。

    function myFunction(myVar_1, myVar_2, callback){
    
        let executed = false;
        listenOnSocket.someEvent(myVar_1,
            function(error, event) {
                if(!executed){
                executed = true
                if (error) callback(null, error);
                else setTimeout(function() {
                           callback(event, null);
                        }, 6000);
            }
           }
        );    
    
        listenOnSocket.someEvent(myVar_2,
            function(error, event) {
                if(!executed){
                executed = true;
                if (!error) callback(event, null); 
                else callback(null, error);
            }
           }
        );
    
    };