LDAPJS searchEntry调用Promise报await错误及返回空数组问题
问题1:await语法报错原因
你给外层的getADUsers加了async关键字不代表内部嵌套的回调函数自动支持await,你报错的await是写在res.on('searchEntry', (entry) => {})的匿名回调函数里,这个回调本身没有被标记为async,所以触发语法错误。
你后续给这个回调加async的修改是正确的,解决了语法报错问题。
问题2:返回空数组的解决方案
res.on('end')的触发时机是LDAP服务端将所有匹配条目全部返回完毕的时间点,但你每个searchEntry回调里的await ConnectAndGetUsersList(...)是独立的异步任务,这些任务不会阻塞end事件的触发,所以end触发时大部分异步任务还没执行完成,adUsersList自然是空的。
你可以通过收集所有条目处理的Promise、等待全部执行完成后再返回结果的方式解决,修改后的参考代码如下:
exports.getADUsers = async (reqst, resp, next) => { let adConnStatus = await ConnectAD() .catch((errConnStatus) => { console.log("Error in connection with Active directory " + errConnStatus); }); if (adConnStatus.status == 0) { var adUsersList = []; // 存储所有条目处理的Promise const entryProcessPromises = []; let client = adConnStatus.client; const opts = { filter: '(ObjectClass=*)', scope: 'sub', attributes: ['cn', 'sid', "objectSid"] }; client.search('dc=domain,dc=com', opts, (err, res) => { if (err) { console.log("Error: " + err); return resp.status(500).send('LDAP search failed'); } res.on('searchEntry', async (entry) => { // 把每个条目的处理逻辑封装成Promise,push到数组 const processPromise = (async () => { var raw = entry.raw; if (raw.objectSid != "undefined" && raw.objectSid != null && entry.object.cn != null && entry.object.cn != "undefined") { let userData = { "Name": entry.object.cn, "SSID": sidBufferToString(raw.objectSid) } var lmn = await ConnectAndGetUsersList(userData.SSID); userData["XYZ"] = lmn.xyz; userData["ABC"] = lmn.abc; adUsersList.push(userData); } })(); entryProcessPromises.push(processPromise); }); res.on('searchReference', (referral) => { console.log('referral: ' + referral.uris.join()); }); res.on('error', (err) => { console.error('error: ' + err.message); return resp.status(500).send('LDAP search error'); }); res.on('end', async (result) => { console.log(result); // 等待所有条目处理完成 await Promise.all(entryProcessPromises); // 此时adUsersList已经填充完成 resp.send(adUsersList); }); }); } }
如果需要兼容部分条目处理失败的场景,可以把Promise.all替换为Promise.allSettled,再自行过滤处理成功的结果即可。
内容的提问来源于stack exchange,提问作者Asad Mehmood
相关产品推荐
相关产品推荐

