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