rahul
rahul

Reputation: 930

use then() to make function run sequentially in node

i want to run loop function in sequence bus the function always gets async is there any way to make it sync without using callback or any external library

file 1

var db = require('./promiseUnderStanding');

var fun = function () {
    for (var i = 0; i < 10; i++) {
        db.getFromDb(i, 0);
    }
}
fun();

file2

var mysql = require("mysql");
module.exports = {
 getFromDb : function (num1,num2) {
    var mysql = require('mysql');
    var connection = mysql.createConnection({
        host: 'localhost',
        user: 'root',
        password: 'root',
        database: 'demo'
    });
    connection.connect();
    connection.query('SELECT '+num1+' + '+num2 +' AS solution', function (error, results, fields) {
        if (error) {
            console.log(err)
        }
        else {
            console.log('The solution is: ', results[0].solution);
        }
    })
    connection.end();
}

}

Upvotes: 2

Views: 562

Answers (3)

Zydnar
Zydnar

Reputation: 1502

If function is async, this means it returns a Promise.

const myFunc = function(){
    return new Promise(function(resolve, reject){
        if(failed){
            reject(dataSendToCatch);
        }if(!failed){
            resolve(dataSendToThen);
        }
    })
};

This is almost the same as:

const myFunc = async function(){
    if(failed) throw new Error();
        return dataSendToThen;
};

After running your function, you can chain async or even sync functions:

myFunc()
.then(function(dataFromResolve){return otherFunc()})
.then(function(dataFromOtherFunc){/*...*/});

For continous handling, filtering, maping received data from async functions is good rxjs library.

Upvotes: 2

Vincent
Vincent

Reputation: 329

Your question seems to be about asynchronous functions so I'm considering the database logic as out of scope.

Use async-await:

File 1:

const fun = async function () {
    for (var i = 0; i < 10; i++) {
        await db.getFromDb(i, 0);
    }
}
fun().then(onFinish).catch(onError);

File 2:

module.exports.getFromDb = function() {
    return new Promise((resolve, reject) => {
        // If success
        resolve(result);
        // If fail
        reject(error);
    });
}
  • A function that returns a Promise is async.
  • A Promise must either resolve or reject.
  • Use await inside async function A when calling async function B to wait for B's promise to resolve or reject
  • If you use the async keyword to define a function, its return value will be wrapped inside an implicit Promise.

Upvotes: 0

Alen Genzić
Alen Genzić

Reputation: 1418

There is no way to run an asynchronous promise synchronously.

However what you are looking for is Promise.all(). Additionally connection.open is also asynchronous, and opening and closing connections to mysql rapidly is not efficient. You should open the connection before your loop, do the queries and then close it (not shown in my example).

Example

File 1:

var db = require('./promiseUnderStanding');

var fun = function () {
    var promises = [];
    for (var i = 0; i < 10; i++) {
        promises.push[db.getFromDb(i, 0)];
    }
    Promise.all(promises).then(function(values){
        console.log(values):
    })
}
fun();

File 2:

var mysql = require("mysql");
module.exports = {
    getFromDb : function (num1,num2) {
    var mysql = require('mysql');
    var connection = mysql.createConnection({
        host: 'localhost',
        user: 'root',
        password: 'root',
        database: 'demo'
    });
    var queryPromise = new Promise(function(resolve, reject) {
        connection.connect(function(err){
            connection.query('SELECT '+num1+' + '+num2 +' AS solution', function (error, results, fields) {
                if (error) {
                    reject(error)
                }
                else {
                    resolve(results)
            }
        });
    })})
    connection.end();
    return queryPromise;
    }
}

Upvotes: 0

Related Questions