我试图遍历AD用户数组并返回一些用户信息。 我现在一直在寻找几个小时,或者更多,并且无法理解activedirectory2 npm软件包的异步特性。
我正在获得我需要的部分结果,但是当迭代用户名列表时,我只会将第一个打印到控制台。
getADUser.js:
var ActiveDirectory = require('activedirectory2');
var config = require('../../conf/conf-ad.json')
var fileTime = require('./w32FiletimeToEpoch')
var moment = require('moment')
// Find user, return all
var ad = new ActiveDirectory(config);
var getADUser = function (sAMAccountName, opts) {
return new Promise(function (resolve, reject) {
ad.findUser(opts, sAMAccountName, function (err, user) {
if (err) {
console.log('ERROR: ' + JSON.stringify(err));
// return;
}
if (!user) {
console.log('User: ' + sAMAccountName + ' not found.');
} else {
if (user.userAccountControl == 514) {
user.userAccountControl = 'Disabled'
} else {
user.userAccountControl = 'Active'
}
if (user.pwdLastSet) {
user.pwdLastSet = `${moment(fileTime(user.pwdLastSet))} - ${moment(fileTime(user.pwdLastSet)).fromNow()}`
}
if (user.lastLogonTimestamp) {
user.lastLogonTimestamp = `${moment(fileTime(user.lastLogonTimestamp))} - ${moment(fileTime(user.lastLogonTimestamp)).fromNow()}`
}
if (user.lastLogon) {
user.lastLogon = `${moment(fileTime(user.lastLogon))} - ${moment(fileTime(user.lastLogon)).fromNow()}`
}
// return;
// return user.promise();
// console.log(user)
// test.push(user)
resolve(JSON.stringify(user));
}
});
})
}
module.exports = getADUser
checkADCompletions.js:
var checks = ['USERONE', 'USERTWO']
let opts = {
attributes: ['sAMAccountName', 'userAccountControl']
};
let checkADCompletions = function (userList) {
let data = []
return new Promise(function (resolve, reject) {
return new Promise(function (res, rej) {
for (let i = 0; i < userList.length; i++) {
getADUser(userList[i], opts)
.then(function (s) {
data.push(s)
}).then(function () {
resolve(data)
})
}
})
})
}
checkADCompletions(checks).then(function (d) {
console.log(d) \\ Only prints the first user details
})
答案 0 :(得分:1)
您可以像这样使用Promise.all
:
let checkADCompletions = function (userList) {
var promises = userList.map(function (user) {
return getADUser(user, opts);
})
return Promise.all(promises);
}
你基本上是在创建一个promises数组,然后同时执行它们。
然后像这样使用它:
checkADCompletions(checks)
.then(function (responses) {
console.log(responses); // this will be an array
})
.catch(function (err) {
// if any of the promises fail, it will enter here.
// err will be the value of the rejected promise
})
Promise.all
will fail even if just one of the checked users fail。因此,您需要很好地处理错误,即处理 ad.findUser
的任何可能结果:
var getADUser = function (sAMAccountName, opts) {
return new Promise(function (resolve, reject) {
ad.findUser(opts, sAMAccountName, function (err, user) {
if (err || user == null) {
console.log('ERROR: ' + JSON.stringify(err));
reject(err);
}
if (user.userAccountControl == 514) {
user.userAccountControl = 'Disabled'
} else {
user.userAccountControl = 'Active'
}
if (user.pwdLastSet) {
user.pwdLastSet = `${moment(fileTime(user.pwdLastSet))} - ${moment(fileTime(user.pwdLastSet)).fromNow()}`
}
if (user.lastLogonTimestamp) {
user.lastLogonTimestamp = `${moment(fileTime(user.lastLogonTimestamp))} - ${moment(fileTime(user.lastLogonTimestamp)).fromNow()}`
}
if (user.lastLogon) {
user.lastLogon = `${moment(fileTime(user.lastLogon))} - ${moment(fileTime(user.lastLogon)).fromNow()}`
}
resolve(user);
});
})
}
答案 1 :(得分:0)
一个简单的解决方法是仅在for循环结束时调用resolve
。
// checkADCompletions.js
var checks = ['USERONE', 'USERTWO']
let opts = {
attributes: ['sAMAccountName', 'userAccountControl']
};
let checkADCompletions = function (userList) {
let data = []
return new Promise(function (resolve, reject) {
for (let i = 0; i < userList.length; i++) {
getADUser(userList[i], opts)
.then(function (s) {
data.push(s)
}).then(function () {
if (i === userList.length) {
resolve(data)
}
})
}
})
})
}
checkADCompletions(checks).then(function (d) {
console.log(d)
})
答案 2 :(得分:-1)
当您致电resolve
时,您会关闭承诺。您启动了两个Promise,然后是for
循环,并在for循环中调用resolve
。因此第一个用户被填充但for循环不会继续,因为Promise已经完成执行。将resolve
移到循环之外,你应该好好去。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve