【问题标题】:Node.js beginner struggling with arrays, promises and AsyncNode.js 初学者在数组、promise 和异步中苦苦挣扎
【发布时间】:2019-01-12 22:04:09
【问题描述】:

这里是一个 node.js(和一般的编码)初学者,正在与 node 的异步特性作斗争。我正在尝试编写一些代码来查找某些 AD 组的成员并将成员名称添加到数组中,按照下面的“getMembers”函数。我只对计算机对象感兴趣,这就是为什么我只有 ad.find 返回“其他”对象。

一旦完成,我希望“processAssets”函数对数组做一些事情——为了测试的目的,只是输出到 console.log。问题是在“getMembers”填充数组之前“processAssets”正在运行。我究竟做错了什么?我意识到答案可能以“几件事”开头......!

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) || (! results)) {return;}
        await _.each(results.other, function(other) {
            assetArray.push(other.cn);
        });
    });
}

function processAssets() {
    console.log("Contents of assetArray (" + assetArray.length + " assets):");
    assetArray.forEach(function(item) {
        console.log(item);
    });
}

提前致谢。

【问题讨论】:

  • 您确定.find 返回Promise 吗?它看起来是基于回调的。
  • 我应该提到我使用的是 activedirectory 包,而不是直接使用广告。我已经更新了问题以使其更清楚。
  • 那么,您确定.find 返回Promise
  • 不,我不确定 - 正如我所说的我是初学者,尽管研究了这个网站和其他网站,但我觉得我错过了一些基本的东西。

标签: arrays node.js asynchronous


【解决方案1】:

你有些事情搞混了。

导致您的直接问题的主要问题是这一行:

Promise.all(cNames.map(cName => getMembers(cName))).then(processAssets())

您需要将一个函数传递给then(),该函数将在promise 解决时被调用。您没有这样做,您将调用processAssets() 的结果传递给它,这具有立即调用processAssets() 的效果。通常你会给我们这样的:

Promise.all(cNames.map(cName => getMembers(cName))).then(() => processAssets())
/*                                                       ^^ pass a function  */

另外你是await 的东西是没有目的的。没有理由在这里等待:

 await ad.find(query + cName + baseOu, async function(err, results) {

ad.find 不返回承诺。一般来说,接受回调的函数不会返回承诺(也许有一些例外,但我想不出任何例外)。如果您想在run()Promise.all 中使用promise,您需要将find 函数包装在promise 中并返回它。比如:

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)
      });
  });  
}

现在getMembers 返回一个解析为ad.find 的结果的promise,您可以在`Promise.all 中使用它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-14
    相关资源
    最近更新 更多