簡體   English   中英

在 Express 的回調中等待 pool.query

[英]Waiting for pool.query inside a callback in Express

我在 Express 的后端點內使用crypto.generateKeyPair

我需要插入在我的數據庫中生成的密鑰,然后在端點內返回插入行的 id 行。

端點代碼如下:

app.post('/createKeys', (req, res) => {
crypto.generateKeyPair('rsa',,
   (err, publicKey, privateKey) => {
        if(!err) {
            let id = myfunction(publicKey.toString('hex'), 
                     privateKey.toString('hex'));

            console.log(id)
        } else {
            res.status(500).send(err);
        }
    });
});

async function myfunction(publicKey, privateKey) {
  await pool.query('INSERT INTO users (publickey, privatekey) VALUES ($1, $2) RETURNING id', 
    [publicKey, privateKey], 
    (error, results) => {
        if (error) {
          throw error;
        }
        resolve(results.rows[0]['id']);
  });
};

但是,在加密回調中,我只得到一個 Promise,如果我不使用異步/等待,則為未定義。 我怎樣才能等待我的函數結果,以便我可以將 id 發回給用戶?

這里有幾個問題:

await僅在您等待 promise 時做一些有用的事情。

當您將回調傳遞給pool.query()時,它不會返回 promise,因此您的await沒有做任何有用的事情。

resolve()不是 function,它存在於使用new Promise((resolve, reject) => { code here })創建新 promise 的上下文之外

throw error inside an asynchronous callback 不會做任何有用的事情,因為無法捕獲該異常,因此無法實現任何體面的錯誤處理。 不要那樣寫代碼。 當您承諾 function(如下所示)時,您可以拒絕 promise,這將提供一種將錯誤傳播回調用者的方法。

您在這里使用await pool.query()的選擇是:

  1. 使用本機支持承諾的數據庫版本,然后不要將回調傳遞給pool.query()以便它返回 promise 告訴您它何時完成。

  2. 通過將pool.query()包裝在新的 promise 中並適當地調用resolve()reject()來承諾您自己的 function。

請記住,不要混合普通回調和 promise。相反,promisify 任何使用普通回調的異步函數,然后使用 promises 執行所有邏輯流。

這是您的myfunction()的手動承諾版本:

function myfunction(publicKey, privateKey) {
    return new Promise((resolve, reject) => {
        pool.query('INSERT INTO users (publickey, privatekey) VALUES ($1, $2) RETURNING id',
            [publicKey, privateKey],
            (error, results) => {
                if (error) {
                    reject(error);
                    return;
                }
                resolve(results.rows[0]['id']);
            });
    });
}

crypto.generateKeyPairP = util.promisify(crypto.generateKeyPair);


app.post('/createKeys', async (req, res) => {
    try {
        const {publicKey, privateKey } = await crypto.generateKeyPairP('rsa');
        const id = await myfunction(publicKey.toString('hex'), privateKey.toString('hex'));
        console.log(id);
        // send your response here, whatever you want it to be
        res.send(id);

    } catch(e) {
        res.status(500).send(e);
    }    
});

請注意,在此實現中, resolvereject函數來自new Promise() - 它們不僅僅存在於空氣中。

但是,可能有一個版本的數據庫或現有數據庫模塊中的一個接口,其中pool.query()可以使用內置的 promise 支持直接返回 promise。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM