繁体   English   中英

为什么我的异步 function 不等待 promise 完成

[英]Why isn't my async function waiting for the promise to be fulfilled

我正在使用 ldapjs 从 ldap 服务器查询用户。 如果我将所有代码只放在一个脚本中而不使用函数,则查询有效并且我得到我需要的结果。

I am now trying to use expressjs to serve a rest endpoint to enable querying of the ldap server, so I moved the ldapjs client.search code into a async function with a promise surrounding the actual search code. 在 promise 代码之后,我有一行使用 await 练习 promise 并将 promise 的结果存储在变量中。 然后我将该变量返回给调用 function 最终将结果作为 json 格式的字符串发送回请求浏览器。

我看到的问题是返回结果的 console.log() 是未定义的,并且出现在 promise 代码中的 console.log 语句之前。 所以看起来异步 function 在 promise 完成之前返回,但我不明白为什么,因为在所有的 promises 和 async/await 示例中,我已经看到这种情况正常工作。

下面是一个没有 expressjs 部分的示例脚本,以确保一切正常。

// script constants:
const ldap = require('ldapjs');
const assert = require('assert');
const ldapServer = "ldap.example.com";
const adSuffix = "dc=example,dc=com"; // test.com
const client = getClient();

const fullName = "*doe*";

var opts = {
  scope: "sub",
  filter: `(cn=${fullName})`,
  attributes: ["displayName", "mail", "title", "manager"]
};
console.log("performing the search");
let ldapUsers = doSearch(client, opts);
console.log("Final Results: " + ldapUsers);

function getClient() {
  // Setup the connection to the ldap server
  ...
  return client;
}

async function doSearch(client, searchOptions) {
  console.log("Inside doSearch()");
  let promise = new Promise((resolve, reject) => {
    users = '{"users": [';
    client.search(adSuffix, searchOptions, (err, res) => {
      if (err) {
        console.log(err);
        reject(err)
      }
      res.on('searchEntry', function(entry) {
        console.log("Entry: " + users.length);
        if (users.length > 11) {
          users = users + "," + JSON.stringify(entry.object);
        } else {
          users = users + JSON.stringify(entry.object);
        }
      });

      res.on('error', function(err) {
        console.error("Error: " + err.message);
        reject(err)
      });
      res.on('end', function(result) {
        console.log("end:");
        client.unbind();
        users = users + "]}";
        resolve(users)
      });
    });
  });


  // resolve the promise:
  let result = await promise;
  console.log("After promise has resolved.");
  console.log(result);
  return result
}

console.log 语句中的 output 如下:

Setting up the ldap client.
ldap.createClient succeeded.
performing the search
Inside doSearch()
Final Results: [object Promise]
Entry: 11
end:
After promise has resolved.
{"users": [{"dn":"cn=john_doe"}]}

我确实删除了创建 ldapjs 客户端的代码并编辑了公司名称,否则这是我的代码。

关于为什么 doSearch function 在 promise 完成之前返回的任何想法将不胜感激。

正如@danh 在评论中提到的那样,您不会await来自doSearch的响应。 由于doSearch是一个async function 它总是会返回一个 promise,因此必须await ed。

作为一种快速而肮脏的方法,您可以将调用包装在立即调用的异步 function 中,如下所示:

// ...

(async () => console.log(await doSearch(client, opts)))();

// ...

有关更多信息,您可以查看有关异步函数的 MDN 文档

我认为提供的代码片段中存在一些问题。 正如@danh 指出的那样,您需要await doSearch调用。 但是,您可能还没有这样做,因为您可能没有使用带有顶级async的环境。 这可能意味着您需要将对doSearch的调用包装在异步 function 中并调用它。 假设您需要等待搜索结果。

// script constants:
const ldap = require('ldapjs');
const assert = require('assert');
const ldapServer = "ldap.example.com";
const adSuffix = "dc=example,dc=com"; // test.com
const client = getClient();

const fullName = "*doe*";

function getClient() {
  // Setup the connection to the ldap server
  ...
  return client;
}

async function doSearch(client, searchOptions) {
  console.log("Inside doSearch()");
  return new Promise((resolve, reject) => {
    users = '{"users": [';
    client.search(adSuffix, searchOptions, (err, res) => {
      if (err) {
        console.log(err);
        reject(err)
      }
      res.on('searchEntry', function(entry) {
        console.log("Entry: " + users.length);
        if (users.length > 11) {
          users = users + "," + JSON.stringify(entry.object);
        } else {
          users = users + JSON.stringify(entry.object);
        }
      });

      res.on('error', function(err) {
        console.error("Error: " + err.message);
        reject(err)
      });
      res.on('end', function(result) {
        console.log("end:");
        client.unbind();
        users = users + "]}";
        console.log(result);
        resolve(users)
      });
    });
  });
}

const opts = {
  scope: "sub",
  filter: `(cn=${fullName})`,
  attributes: ["displayName", "mail", "title", "manager"]
};

(async function runAsyncSearch () {
  console.log("performing the search");
  try {
    const ldapUsers = await doSearch(client, opts); // Await the async results
    console.log("After promise has resolved.");
    console.log("Final Results: " + ldapUsers);
  } catch (err) {
    console.error(err.message);
  } 
})();  // Execute the function immediately after defining it.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM