Facing issue for synchronous operation in NodeJS

nodejs promise
node js concurrency issues
async/await
node js execute function after another function completes
node js tutorial
async/await in node js
nodejs event loop
nodejs sleep

Below code have 2 files and having client.js which calls to server file but didn't get the synchronous output. I tried with promise, bluebird, async_await but didn't get success. Expected output is a sequence of the alphabet in a console.

Do not use settimout.

Understanding of files. server.js : server file is having NodeAPI which content only routing.

Client.js : logic which tried is in this file

You need to use two console, first run server.js and second console need to run client.js and output will be print in server.js console.

 Expecting output is 
    a
    b
    c
    d
    e

 /////////////////server.js/////////////////
    var express = require('express');
    var bodyParser = require('body-parser')
    var app = express();

    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({
        extended: true
    }));

    app.post('/', function (req, res) {   
       console.log(req.body.test)
       res.status(200).send('ok');
    });

    var server = app.listen(3000, function () {
        console.log('ok');
    });

    //////////////client.js///////////////////


    //var Promise = require('bluebird');
    var request = require('request');
    console.log('server file called');
    var array_data = ['a', 'b', 'c', 'd', 'e'];


    // var promises = [];
    // for(let i = 0; i < array_data.length; i++) {
    //     var promise = request.post({url: 'http://localhost:3000',form : {key:array_data[i]}});
    // }

    // var page = 0;
    // var last_page = array_data.length;

    // (function loop() {
    //     if (page < last_page) {
    //         request.post({
    //             url: 'http://localhost:3000',
    //             form: 'test=' + array_data[page]
    //         }, function (error, response, body) {
    //             page++;
    //             loop();
    //         });
    //     }
    // }());


    // async function loopAsync() {
    //     for (let i = 0; i < array_data.length; i++) {
    //         await request.post({
    //             url: 'http://localhost:3000',
    //             form: 'test=' + array_data[i]
    //         });
    //     }
    // }
    // loopAsync();

    async function loopAsync() {
        var page = 0;
        var last_page = array_data.length;
        while (page < last_page) {
            await request.post({
                url: 'http://localhost:3000',
                form: 'test=' + array_data[page]
            });
            page++;
        }
    }
    loopAsync();


[enter image description here][1]


  [1]: https://i.stack.imgur.com/WVlut.png

You can use util.promisify.

Here is sample code

const reqpost = util.promisify(request.post); 

async function loopAsync() {
    var page = 0;
    var last_page = array_data.length;
    while (page < last_page) {
      await reqpost({
        url: 'http://localhost:3000',
        form: 'test=' + array_data[page]
      });
     page++;
 } } 

loopAsync();

Mastering Node.js, avoid synchronous coding—if facing a problem where a synchronous operation seems the only solution, it is likely that the problem has been misunderstood. Node.js is single-threaded for asynchronous processing. While preparing your order your thread (waiter) is waiting for the response.This is called blocking or synchronous architecture.A non-blocking call initiates the operation.

request.post is a function that takes request options and a callback like this.

function request(letter, callback = () => {}) {
    setTimeout(() => {
        console.log(letter);
        callback();
    }, Math.random() * 1000);
}

What you're doing is calling that function without supplying a callback:

async function clientWithRequest() {
    const letters = ['a', 'b', 'c'];

    for(let i = 0; i < letters.length; i++) {
        await request(letters[i]);
    }
}

here, the requests are all fired off at the same time and will return in an indeterminate order.

What you need to do if you want to use async is make your request return a promise. Under the hood, await is really just doing request.then(somethingElse()). So if you change your request to return a promise like:

function requestPromise(letter) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log(letter);
            resolve();
        }, Math.random() * 1000);
    });
}

your await code will then work as expected. Effectively it's doing.

request('a').then(() => request('b')).then(() => request('c'));

The Top 10 Most Common Mistakes That Node.js Developers Make , In Node.js, callbacks used to be the only way asynchronous elements of your One common Node.js issue related to using callbacks is calling them more than once. implement the important mathematical operations on large precision numbers, If i may , facing an issue where in i have two services running and i have  NodeJS does support Synchronous Requests. It wasn’t designed to support them out of the box, but there are a few workarounds if you are keen enough, here is an example: It wasn’t designed to support them out of the box, but there are a few workarounds if you are keen enough, here is an example:

https://github.com/request/request#forms

Since you are forming the form data string yourself via Node

Is it possible that if you can just let request help you form the encoded string via their form method?

const jobs = [];
const array_data = [
  'a',
  'b',
  'c',
  'd',
  'e',
];
require('request');
const request = require('request-promise');
async function loopAsync() {
  for(const char of array_data) {
    jobs.push(
      request.post({
          url: 'https://marble-scene.glitch.me/',
          form: {
            test: char
          }
      })
    );
  }
  const output = await Promise.all(jobs);
  output.forEach(char => console.log(char)); // # a b c d e
}
loopAsync();

Overview of Blocking vs Non-Blocking, Synchronous methods in the Node.js standard library that use libuv are the most commonly used blocking operations. Native modules may also have blocking  A synchronous HTTP request will wait for the request to be made and full response to come. Synchronous HTTP requests are possible in Node.js with the use of Javascript Promises, async and await.

As an alternative to importing additional libraries. you can simply "promisify" the callback dependent request.post method.

async function loopAsync() {
        var page = 0;
        var last_page = array_data.length;
        while (page < last_page) {
            await new Promise((resolve, reject) => {
                request.post({
                  url: 'http://localhost:3000',
                  form: 'test=' + array_data[page]
                 }, function(err,httpResponse,body){
                   if (err) reject(err);
                   else resolve({httpResponse,body});
                 });
                 page++;
            });
        }
}
loopAsync()

Synchronous Pull problem · Issue #891 · googleapis/nodejs-pubsub , GitHub is home to over 50 million developers working together to host and I faced this issue today, for example, earlier acknowledge function  In Node.js, JavaScript that exhibits poor performance due to being CPU intensive rather than waiting on a non-JavaScript operation, such as I/O, isn't typically referred to as blocking. Synchronous methods in the Node.js standard library that use libuv are the most commonly used blocking operations.

As I did the R&D, request module is not returned promise so for that need to use request-promise library.

let request = require('request');
    let rp = require('request-promise');
    var array_data = ['a', 'b', 'c', 'd', 'e'];    
    //with the use of request-promise library 
        async function loopAsync() {
            var page = 0;
            var last_page = array_data.length;
            while (page < last_page) {
                var options = {
                    method: 'POST',
                    uri: 'http://localhost:3000',
                    body: {
                        test: array_data[page]
                    },
                    json: true // Automatically stringifies the body to JSON
                };
                await rp(options);
                page++;
            }
        }
        loopAsync();

Possible to await non-promise synchronously? · Issue #33 · tc39 , The answers to these questions impact the asynchronous generator proposal. GitHub is home to over 50 million developers working together to host and I have found the opposite to be true, in both epoll(7) + read(2) and  The fs.readFileSync() method is an inbuilt application programming interface of fs module which is used to read the file and return its content.. In fs.readFile() method, we can read a file in a non-blocking asynchronous way, but in fs.readFileSync() method, we can read files in a synchronous way, i.e. we are telling node.js to block other parallel process and do the current file reading process.

Node.js Async Best Practices & Avoiding Callback Hell, and techniques you have at your disposal when handling Node.js asynchronous operations. The Problem with Node.js Async essentially the opposite of promisify , which takes an async function that returns a promise,  One of the challenges is that the type of crypto operations that are typical in Node.js right now do not run any faster async than they do sync, and there ends up being additional overhead introduced by the mechanisms needed to make them run async.

Get Started With Node: An Introduction To APIs, HTTP And ES6+ , You've probably heard of Node.js as being an “asynchronous JavaScript If a synchronous operation can manage to complete without blocking the thread or to the promise completed successfully, and rejected meaning the opposite. of third-party packages that solve common problems in JavaScript. By making the default 0, I think we can start applying this to the synchronous rimraf. I think retries should be opt-in, particularly for synchronous operations, which can block the event loop for a while. I also think that the async and sync versions should have consistent handling of retry logic.

“Node.js is one of the worst things to happen to the software industry , In Node.js, you are explicitly synchronous / implicitly async. It's great for a lot of things, but makes it hard to read and reason about synchronous operations that I think a lot of the issues with JavaScript are around the movement of 10x, and boring old synchronous Jetty is still 2x better than NodeJS  Node.js promotes an asynchronous coding style from the ground up, in contrast to many of the most popular web frameworks. There are a number of important things to be aware of when learning to write asynchronous code - otherwise, you will often find your code executing in extremely unexpected ways.

Comments
  • you can use await with promises so use request-promise npmjs.com/package/request-promise#request-promise
  • Hi @Ariz, I already tried with promise request but didn't get success.
  • @Ariz is right, you can only use await with a function that returns a promise, request on its own won't do that. Can you share the code you used with request-promise?
  • The first thing I would do is use NPM debugging break points to assure that the requests are being dispatched in the expected order, this would rule out any issue with the client.
  • setTimeout is not allow to use, its not get proper response as per server operation
  • @nigammehta Will Munn gave that as an example to prove his point for asynchronus operation. If you want to use async and await wrap yourrequest.post function inside a promise as shown in the example
  • Yes, it's just an example, and as @Joseph Persie said in his answer, you can use promisify with request.post to acheive this or alternatively use the request-promise module
  • As provided your answer is not getting proper output, it seems same as past which I shared my code
  • Thank you, your answer is valid but wants depth understanding which you used async_await with promise, Could you please share the details?
  • @nigammehta The await construct expects a promise which request.post does not return. By wrapping it in a Promise invocation function, you turn it into a function that returns a promise which in turn is expected by the await construct.
  • Thanks for sharing the depth of request promise.
  • Insted of this I used request-promise library for it and got another solution.