簡體   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