By RST


2018-09-14 15:45:30 8 Comments

I have searched high and low but can't get my head around promises. What I do understand is how to define one promise and use its result by using .then.

What I do not understand is how I can create a loop to query the database for different blocks of records. This is needed due to a limit set on the number of records to query.

The predefined promise api call is used like this:

let getRecords = (name) => {
  return new Promise((resolve,reject) => {
    xyz.api.getRecords(name, 1000, 1000, function(err, result){
      // result gets processed here.
    resolve(//somevariables here);
    });
)};

going with what I am used to, I tried:

for (let i=1; i<90000; i+=500) {
    xyz.api.getRecords('james', i, 500, function(err, result){
      // result gets processed here.
    });
}

But then I can't access the information (could be my wrong doing) Also tried something like this:

function getRecords(name,i){
        xyz.api.getRecords(name, i, 500, function(err, result){
          // result gets processed here.
        });
};

for (let i=1; i<90000; i+=500) {
       var someThing = getRecords('james', i);
}

All tutorials only seem to use one query, and process the data.

How do I call the api function multiple times with different arguments, collect the data and process it once everything is retrieved? Only thing I can think of is, to write info to a file, terrible thought.

2 comments

@Brian 2018-09-14 15:57:32

By returning a promise and calling your asynchronous function inside, you can resolve the result and then use it this way:

function getRecords (name, i) {
    return new Promise((resolve, reject) => {
        xyz.api.getRecords(name, i, 500, (err, result) => {
            if (err) {
                reject(err);
            } else {
                resolve(result);
            }
        });
    });
}

for (let i = 1; i < 90000; i * 500) {
    getRecords('james', i)
        .then(result => {
            // do stuff with result
        })
}

Or, using async / await syntax:

async function getRecords (name, i) {
    return new Promise((resolve, reject) => {
        xyz.api.getRecords(name, i, 500, (err, result) => {
            if (err) {
                reject(err);
            } else {
                resolve(result);
            }
        });
    });
}

// this needs to happen inside a function, node does not allow top level `await`
for (let i = 1; i < 90000; i *= 500) {
    const result = await getRecords('james', i);
    // do stuff
}

Get all of your records at once

const requests = [];
for (let i = 1; i < 90000; i * 500) {
    requests.push(getRecords('james', i));
}
const results = await Promise.all(requests);

@ponury-kostek 2018-09-14 15:52:57

Using async/await

(async () => {
    function getRecords(name,i){
        // create new Promise so you can await for it later
        return new Promise((resolve, reject) => { 
            xyz.api.getRecords(name, i, 500, function(err, result){
                if(err) {
                    return reject(err);
                }
                resolve(result);
            });
        });

    }
    for (let i = 1; i < 90000; i += 500) {
        // wait for the result in every loop iteration
        const someThing = await getRecords('james', i); 
    }
})();

To handle errors you need to use try/catch block

try {
    const someThing = await getRecords('james', i);
} catch(e) {
    // handle somehow
}

Using only Promises

function getRecords(name, i) {
    // create Promise so you can use Promise.all
    return new Promise((resolve, reject) => { 
        xyz.api.getRecords(name, i, 500, function (err, result) {
            if (err) {
                return reject(err);
            }
            resolve(result);
        });
    });
}

const results = [];
for (let i = 1; i < 90000; i += 500) {
    // push Promise's to array without waiting for results
    results.push(getRecords("james", i));
}
// wait for all pending Promise's
Promise.all(results).then((results) => { 
    console.log(results);
});

let count = 0;

function getRecords(name, i) {
	return new Promise((resolve, reject) => {
		setTimeout(() => {
			// example results
			resolve((new Array(10)).fill(0).map(() => ++count));
		}, 100);
	});
}

const results = [];
for (let i = 1; i < 9000; i += 500) {
	results.push(getRecords("james", i));
}
Promise.all(results).then((results) => {
	console.log("Results:", results);
  console.log("Combined results:",[].concat(...results));
});

To handle errors you need to use .catch() block

Promise.all(results).then((results) => { ... }).catch((error) => {
    // handle somehow
});

@RST 2018-09-14 15:57:22

thanks for the examples. I will give it a try.

@Patrick Roberts 2018-09-14 16:05:30

Almost. I know it was a mistake from OP's code but this will never exit the for loop.

@ponury-kostek 2018-09-14 16:08:37

@PatrickRoberts You are right

@RST 2018-09-16 15:28:38

Thanks I got it running for one name. My next challenge will be to make it work for an array of names.

Related Questions

Sponsored Content

36 Answered Questions

[SOLVED] How can I update NodeJS and NPM to the next versions?

7 Answered Questions

[SOLVED] Why do we need middleware for async flow in Redux?

2 Answered Questions

Using NodeJS promise to query MongoDB

0 Answered Questions

Lose of global data sometimes inside promise chain nodejs

3 Answered Questions

2 Answered Questions

[SOLVED] Nodejs promise all not running as expected

1 Answered Questions

[SOLVED] Chain functions using bluebird promises in NodeJS

1 Answered Questions

[SOLVED] nodejs pg-promise get variable outside function scope

2 Answered Questions

[SOLVED] Named promise results with q.all in NodeJS

  • 2016-01-07 14:54:46
  • lascort
  • 573 View
  • 1 Score
  • 2 Answer
  • Tags:   node.js promise q

1 Answered Questions

[SOLVED] NodeJS Promise behaviour query

Sponsored Content