[英]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.