【问题标题】:Websocket - Waiting for a http request callback to execute before next pusher eventWebsocket - 在下一个推送事件之前等待 http 请求回调执行
【发布时间】:2019-07-25 20:15:52
【问题描述】:

所以我正在使用 websockets 来处理来自网站 API 的数据。对于每个新事件,我还会将一些 http 请求发送回网站以获取更多数据。到目前为止,一切都运行良好,但现在我开始使用异步请求来加速它,事情变得有点不同。我的代码用于处理一个事件,然后继续处理下一个事件(这些事件来得非常快——大约每秒 10 个)但现在它似乎忽略了异步(非阻塞)部分并继续进行下一个事件和这样它就跳过了一半以上的代码。请注意,代码在 Pusher 之外运行良好。我正在使用“推送客户端”模块。我的代码如下所示:

var Request = require("request");
var requestSync = require('sync-request');
var Pusher = require('pusher-client');

var events_channel = pusher.subscribe('inventory_changes');
events_channel1.bind('listed', function(data)
{
    var var2;
    //Async request (to speed up the code)
    function myFunction(callback){
        request("url", function(error, response, body) {
            if (!error && response.statusCode == 200) 
            {
                result = JSON.stringify(JSON.parse(body));
                return callback(null, result);
            } 
            else 
            {
                return callback(error, null);
            }
        });
    }

    myFunction(function(err, data){
        if(!err)
        {
            var2 = data
            return(data);
        }
        else
        {
            return(err);
        }
    });


    //The part of the code below waits for the callback and the executes some code
    var var1 = var2;

    check();
    function check() 
    {
        if(var2 === var1)
        {
            setTimeout(check, 10);
            return;
        }
        var1 = var2;

        //A CHUNK OF CODE EXECUTES HERE (connected to the data from the callback)
    }
});

总而言之,代码可以工作,但由于推送器跳过异步请求,所以不能在推送器内部。在处理下一个事件之前,我如何让推送器等待我的异步请求完成(我不知道)?如果你碰巧知道,请告诉我:)

【问题讨论】:

    标签: node.js websocket callback pusher


    【解决方案1】:

    你需要实现一个队列来处理一个接一个的事件。我很好奇它以前是如何工作的,即使没有Pusher,你也必须为它实现一些队列机制。

    const eventsQueue = []
    
    events_channel1.bind('listed', function(data) {
      eventsQueue.push(data)
      handleNewEvent()
    })
    
    let processingEvent = false
    function handleNewEvent() {
      if (processingEvent) return // do nothing if already processing an event
      processingEvent = true
      const eventData = eventsQueue.shift() // pick the first element from array
      if (!eventData) return // all events are handled at the moment
      ... // handle event data here
      processingEvent = false
      handleNewEvent() // handle next event
    }
    

    另外,当你不再需要它时,你应该调用clearTimeout 方法来清除你的超时。

    最好使用 Promise 或 async/await 而不是回调。您的代码将更易于阅读和维护。

    【讨论】:

    • 感谢您的回答!我遇到了一个错误:“processingEvent = false; SyntaxError: Rest parameter may not have a default initializer”。如果您知道原因,请告诉我:)
    • processingEvent = false 行之前删除...,我只是将它添加为您的代码的占位符
    • 出于某种原因,"// 在此处处理事件数据" 行只会执行一次。此外,该函数似乎只会调用自己一次(在开始时),然后即使有更多元素要处理,它也只会被推送者调用。
    • 每个事件执行一次,在它的主体结束时也被调用
    • 这很奇怪。我放了一个 console.log(1); 在那里,它只显示一次,而如果我在 "if (processingEvent) {return}"下方放了一个 1 行> 行它会被执行两次。如果我把它作为函数的第一行,它会为每个事件执行。 processingEvent 变量似乎有些地方不太对劲。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多