Dealing with asynchronous tasks in JavaScript

I am currently delving into the world of Node development and struggling to grasp the asynchronous nature of JavaScript and Node.js. My project involves creating a microservices backend web server using Express in the gateway service, which then translates REST requests into a series of messages published through RabbitMQ's async messaging module (amqplib). These messages are subscribed to by other services for processing and responding accordingly.

Here is an excerpt of my service responsible for handling asynchronous requests from the gateway:

amqp.connect('amqp://172.17.0.2', function(err, conn) {
  console.log("connection created");
  conn.createChannel(function(err, ch) {
    console.log("channel created");
    var exchange = 'main';

    ch.assertExchange(exchange, 'topic', {durable: true});

    ch.assertQueue('', {exclusive: true}, function(err, q) {
      console.log(' [*] Waiting for logs. To exit press CTRL+C');

      ch.bindQueue(q.queue, exchange, "VENUE_TOPIC.PENDING_STATUS.*.*");

      ch.consume(q.queue, function(msg) { 
        console.log(" [x] %s:'%s'", msg.fields.routingKey, msg.content.toString());
        var pending_event = JSON.parse(msg.content.toString())
        console.log(pending_event.payload.id == 2)
        console.log(pending_event.payload.id)
        if (pending_event.payload.id == 1) { 
          var venue = getVenueByID(pending_event.payload.id);
          const approved_event = new Event("VENUE_TOPIC", "APPROVED_STATUS", false, "READ_METHOD", {"venue":venue});
          var key = approved_event.getMetaAsTopics();

          var msg = Buffer.from(JSON.stringify(approved_event.getEventAsJSON()));

          ch.assertExchange(exchange, 'topic', {durable: true});
          ch.publish(exchange, key, msg, {persistent: true});
          console.log(" [x] Sent '%s'", msg);        
        } else if (pending_event.payload.id == 2) {
          sleep(10000); //this function checks the OS's clock to count time in ms
          var venue = getVenueByID(pending_event.payload.id);
          const approved_event = new Event("VENUE_TOPIC", "APPROVED_STATUS", false, "READ_METHOD", {"venue":venue}); 
          var key = approved_event.getMetaAsTopics();

          var msg = Buffer.from(JSON.stringify(approved_event.getEventAsJSON()));

          ch.assertExchange(exchange, 'topic', {durable: true});
          ch.publish(exchange, key, msg, {persistent: true});
          console.log(" [x] Sent '%s'", msg);
        }
      }, {noAck: true});
    });
  });
});

Imagine having two incoming requests, one lengthy and the other quick. If the long request arrives before the short one, there will be a delay due to the nature of the long process taking precedence. In this scenario, ID === 2 represents the long process while ID === 1 symbolizes the shorter one.

Is there a way to handle both requests concurrently without letting the lengthier operation hold up the quicker one until completion?

Answer №1

Unfortunately, my SO reputation isn't sufficient for commenting, but I will do my best to offer valuable insights.

If the sleep function refers to the npm package found here, then the behavior you are experiencing is expected - known as blocking behavior. If you intend to execute non-blocking tasks (such as web requests) within your consume function, Node will continue processing messages without interruption. However, if your task involves intensive CPU work that blocks processing of incoming messages, it's best to delegate this work to a separate worker.

Consider using the following code snippet for a "non-blocking" sleep function:

setTimeout(() => {
    var venue = getVenueByID(pending_event.payload.id);
    const approved_event = new Event("VENUE_TOPIC", "APPROVED_STATUS", false, "READ_METHOD", {
        "venue": venue
    });
    var key = approved_event.getMetaAsTopics();

    var msg = Buffer.from(JSON.stringify(approved_event.getEventAsJSON()));

    ch.assertExchange(exchange, 'topic', {
        durable: true
    });
    ch.publish(exchange, key, msg, {
        persistent: true
    });
    console.log(" [x] Sent '%s'", msg);
}, 10000);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Curious about how to utilize Gridfs to upload files or videos larger than 16mb with the help of express, mongoose, and mongodb?

I'm encountering an issue with my code. It works fine for uploading images, but when I try to upload videos or files larger than 16mb, it fails. I am a beginner and seeking help on what to do next. const Freecoursevideo = require("../models/freec ...

What is the best way to eliminate a specific object from an array in Mongoose based on a certain value?

I am new to backend development and currently working with Mongoose, Express, and Node.js. In my MongoDB database, I have a collection of users. My goal is to delete a specific favorite item in the user's favorites array by matching it with the favori ...

What is the best way to determine if a checkbox has been selected in ExtJS?

I have a panel with a checkbox inside it. I am trying to figure out how to check if the checkbox is selected or not using an external function. Can someone please assist me with this? this.currentManagerPanel = new Ext.Panel({ border: false, wid ...

Setting up angular-cli project for rc5- Step by step guide

Trying to integrate angular-cli with angular 2 rc5 but facing challenges: The issue of 'Promise' not being found After attempting to install 'npm install -g angular-cli@webpack', typings did not get installed, resulting in WebStorm un ...

What is the best way to apply a CSS class to a div element without affecting its child elements using JavaScript?

Currently, I am using JavaScript to add and remove a CSS class through a click event. Within my div structure, I have multiple similar divs. While I can successfully add and remove the class from my main div, I am facing an issue where the class is also ap ...

"Enhance User Experience with Multilevel Dropdowns in Bootstrap 4 - Submenus Aligned to the Top

I recently embarked on a project that involved using Bootstrap 4.4, The project is an eCommerce grocery store with departments comprising categories and subcategories. The main menu became very lengthy when using the default code, so I encountered some al ...

After an asynchronous query using Mongoose in an Express route, I am unable to make any changes to the variable. It remains unchanged

I am facing an issue with modifying an empty array let last_activity = [] based on the result of a Mongoose query within an Express route. For troubleshooting purposes, I am currently trying to change it to [1, 2, 3]. Despite attempting different approache ...

Is there a way to effectively organize an RSS feed using the .isoDate parameter while ensuring that the feed's elements remain interconnected (such as title and link)?

My goal is to organize the RSS feed by the most recent item while ensuring that each title corresponds correctly with its link. Currently, I am parsing and displaying the feed using the .isoDate property, but I am unsure of the best approach to achieve thi ...

Using AJAX to submit a PHP form without refreshing the page

Currently, I am facing an issue with my PHP and AJAX code for posting data without redirecting the page. Surprisingly, the script works perfectly on the login page but not on other pages. The main difference I observed is that the login page uses if (empty ...

Choosing the state object name dynamically within a React JS component

I have a quick question about updating state in React. How can I change a specific object in a copy of the state that is selected using e.target.name and then set to e.target.value? For example, if I want to change newState.age when e.target.name = age i ...

Is it possible for a form to direct submissions to various pages depending on the value of certain fields

I need to set up a text field and submit button that will redirect users based on their input: index.html: If the user inputs "123" in the text box and clicks submit, they should be redirected to john.html page. AND If the user inputs "456" and clicks s ...

Properly aligning text with checkboxes using HTML/CSS and tags like <span> or <div>

My goal is to have the text displayed as a block in alignment with the checkbox, adjusting based on the sidebar's width. For reference: Current Layout Preferred Layout I have shared the code on CodePen (taking into account screen resolution and wi ...

Unable to transform object into a primitive value using imported JSON data

https://i.sstatic.net/HcY5M.png I am currently working on creating a Vuetify component dynamically within a Nuxt project, as discussed in this Stack Overflow thread (Using different text values with Vuetify component). To achieve this, I am importing and ...

javascript monitoring numerous socket channels for echoes

Currently, I am in the process of developing a chat application. On the server side, I am utilizing: php, laravel 5.4, and pusher. On the client side, I have incorporated vue.js along with laravel-echo. Initially, I successfully created a "public chat roo ...

Switching between two states of a single 'td' element within a column

I am trying to implement a feature where only specific elements in the fourth column of a four-column table toggle when clicked. For example, clicking on an element in the fifth row third column should toggle the corresponding element in the fifth row four ...

Conserving node.js native imports for Electron with rollup

I am working on a project using Electron, Svelte, and Typescript. Initially, I used a specific template from here, but it restricted access to node.js built-in imports like fs for security reasons in the browser/electron frontend. However, I do not requir ...

Align images of varying sizes vertically within div containers, even when the image is larger than the div itself

I'm facing a challenge when it comes to aligning images vertically inside divs. The problem arises due to the following conditions: The images will have varying and unknown sizes. These images are larger than the divs they are contained in, requiri ...

Error Message: Unexpected character "C" found in JSON response from Ionic 2 Http GET request

Trying to execute a GET request and extract data from the response. this.http.get('http://localhost:8888/maneappback/more-items.php').subscribe(res => { console.log(res.json()); }, (err) => { console.log(err); }); An error message ...

Incorporate the xml2js JavaScript library with Angular 2 for enhanced functionality

I've been attempting to utilize xml2js as an XML parser within my Angular 2 (RC 1 with TypeScript) web application. Unfortunately, I've encountered several errors without finding a solution that works. Here is the detailed process I followed: ...

Issues with data within a Vue.js pagination component for Bootstrap tables

Currently, my table is failing to display the data retrieved from a rest api (itunes), and it also lacks pagination support. When checking the console, I'm encountering the following error: <table result="[object Object],[object Object],[object Ob ...