Search code examples
javascriptnode.jsecmascript-6es6-promise

How to make this piece of code asynchronous via promises?


Any Glue. Please do not give example of SETTIMEOUT.

My supervisor said that it is unnecessary having more then() statement if the then()'s do not return any new promise.I could not get it completely, I have looked at Exploring ES6 but there is no very well example of my situation.

let readData = new Promise(function (resolve, reject) {
    fs.readFile('/home/geek/Desktop/activity-logs.csv', 'utf8', (err, data) => {
        if (err)
            reject();
        resolve(data);

    });

});

readData
    .then((data) => {
        bankLogs = splitString(data, ';')
    })
    .then(() => {
        for (let index = 2; index < bankLogs.length; index += 5) {
            objectOfUsers[bankLogs[index]] = {}
            temporarySymbols.push(bankLogs[index].concat(bankLogs[index + 1]));
        }
        Object.keys(objectOfUsers).forEach(function (element) {
            objectKeys.push(element)
        });
        for (let index = 0; index < objectKeys.length; index++)
            createObject(index);
        console.log(objectOfUsers)
    })
    .catch((err) => console.log('Error happened : ' + err));


Solution

  • From your code snippet you implemented Promise chain where resolving one promise initializes and returns new one.

    Something like:

    let readData = new Promise(/* ... */);
    
    readData.then((data) => {
            let promise2 = new Promise(/* ... */);
            return promise2;
        }).then(() => {
            // ...
        })
        .catch((err) => console.log('Error happened : ' + err));
    

    However after resolving readData you only wrote simple logic and there is no new promises: bankLogs = splitString(data, ';')

    So It should be:

    let readData = new Promise(function (resolve, reject) {
        fs.readFile('/home/geek/Desktop/activity-logs.csv', 'utf8', (err, data) => {
            if (err)
                reject();
            resolve(data);    
        });    
    });
    
    readData.then((data) => {
        var bankLogs = splitString(data, ';')
    
        for (let index = 2; index < bankLogs.length; index += 5) {
            objectOfUsers[bankLogs[index]] = {}
            temporarySymbols.push(bankLogs[index].concat(bankLogs[index + 1]));
        }
        Object.keys(objectOfUsers).forEach(function (element) {
            objectKeys.push(element)
        });
        for (let index = 0; index < objectKeys.length; index++)
            createObject(index);
        console.log(objectOfUsers)
    })
    .catch((err) => console.log('Error happened : ' + err));
    

    If you use bankLogs inside Promise only, make it private.


    Promise chain approach we use mostly for good code readability and handling one error callback for all promises.

    Edit

    You can pass value through Promise chain by using some wrapper object or list of items (example):

    'use strict';
    
    var fs = require('fs');
    
    let readData = new Promise(function (resolve, reject) {
        fs.readFile('/Users/maxim/Appsflyer/projects/ZEVEL/file1.txt', 'utf8', (err, data) => {
            if (err)
                reject();
    
            var obj = {
                data: data,
                bankLogs: {} // in 1st Promise initialize bankLogs
            };    
            resolve(obj);    
        });    
    });
    
    // 2nd dummy Promise 
    let newReadData = new Promise(function (resolve, reject) {
        fs.readFile('/Users/maxim/Appsflyer/projects/ZEVEL/file2.txt', 'utf8', (err, data) => {
            if (err)
                reject();
            resolve(data);
    
        });
    
    });
    
    readData.then((obj1) => {   
    
        obj1.bankLogs.value = "someValue";
    
        return newReadData.then(function(data2){       
            obj1.data2 = data2;
            return obj1;
        });
    }).then((dataTotal) => {   
        console.log(dataTotal);
    
    })
    .catch((err) => console.log('Error happened : ' + err));