Node.js beginner struggling with arrays, promises and Async
Clash Royale CLAN TAG#URR8PPP
Node.js beginner struggling with arrays, promises and Async
A node.js (and coding in general) beginner here, struggling with the async nature of node. I'm trying to write some code that will look up the members of certain AD groups and add the member names to an array, as per the "getMembers" function below. I'm only interested in computer objects, which is why I only have ad.find returning "other" objects.
Once that is complete, I want the "processAssets" function to do something with the array - for the purpose of testing, just ouptutting to the console.log. The problem is that "processAssets" is running before "getMembers" has populated the array. What am I doing wrong? I realise the answer may begin with "several things"...!
const ActiveDirectory = require('activedirectory');
var ad = new ActiveDirectory(config);
var query = 'memberOf=cn=';
var cNames = [
'group1',
'group2',
'group3'
];
var baseOu = ',ou=Groups,dc=example,dc=com';
function run(cNames)
Promise.all(cNames.map(cName => getMembers(cName))).then(processAssets())
async function getMembers(cName)
await ad.find(query + cName + baseOu, async function(err, results)
if ((err) );
function processAssets()
console.log("Contents of assetArray (" + assetArray.length + " assets):");
assetArray.forEach(function(item)
console.log(item);
);
thanks in advance.
.find
Promise
I should have mentioned that I'm using the activedirectory package, not ad directly. I've updated the question to make that clearer.
– Adam
Aug 6 at 0:36
So, are you sure that
.find
returns a Promise
?– CertainPerformance
Aug 6 at 0:37
.find
Promise
No I'm not sure - as I said I'm a beginner, and despite researching this website and others I feel I've missed something fundamental.
– Adam
Aug 6 at 0:40
1 Answer
1
You have some things mixed up.
The main problem causing your immediate issue is this line:
Promise.all(cNames.map(cName => getMembers(cName))).then(processAssets())
You need to pass a function to then()
which will be called when the promise resolves. You are not doing that, you are passing it the result of calling processAssets()
, which has the effect of calling processAssets()
immediately. Typically you would us something like:
then()
processAssets()
processAssets()
Promise.all(cNames.map(cName => getMembers(cName))).then(() => processAssets())
/* ^^ pass a function */
Additionally you are await
things for no purpose. There's no reason to await here:
await
await ad.find(query + cName + baseOu, async function(err, results) {
ad.find
doesn't return a promise. In general functions that take callbacks don't return promises (maybe there are some exceptions, but I can't think of any). If you want to have a promise to use in run()
's Promise.all
you need to wrap the find
function in a promise and return it. Something like:
ad.find
run()
Promise.all
find
function getMembers(cName)
return new Promise((resolve, reject) =>
ad.find(query + cName + baseOu, function(err, results)
if (err) return reject(err)
// I'm making some assumptions about results. But hopefully this gives
// a good enough idea
let data = results.other.map(other => other.cn)
resolve(data)
);
);
Now getMembers
returns a promise that resolves to the result of ad.find
and you can use it in `Promise.all.
getMembers
ad.find
thanks for the explanation Mark.
– Adam
Aug 7 at 4:20
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Are you sure that
.find
returns aPromise
? It looks to be callback-based.– CertainPerformance
Aug 6 at 0:26