Не понимаю этот асинхронный вызов с Axios - PullRequest
0 голосов
/ 07 февраля 2019

Я использую узел 10+, и у меня есть эта функция, где я делаю запрос к базе данных и жду результата и возвращаю его:

var test3 = (req,res,query) => {   
    var conn = new sql.ConnectionPool(dbconfig);
    var req = new sql.Request(conn);
    var result;
    return  conn.connect().then(async() => {       
            result = await req.query(query);               
            conn.close();
            return result;

           }).catch(e => {
                return e;
           }).finally(() => {
                conn.close();
           });   
}

Во-первых, я хотел бы знать, почему я долженвернуть блок conn.connect () ..

return  conn.connect().then(async() => {...  

Я знаю, что это как-то связано с цепочкой обещаний, я думаю, но я не понимаю почему, потому что мой асинхронный вызов БД уже разрешен из await dbcallфункция ... и я просто возвращаю результат из функции

Затем у меня есть маршрутизатор, где я вызываю функцию API здесь:

router.get("/api/compareCount",  function(req,res) {
    var query = `SELECT COUNT(*) as count
      FROM [DublettenReferenzmenge].[dbo].[DocumentForElasticsearch] where lastChange < dateadd(day,-1,getdate())`;
      var query2 = `SELECT COUNT(*) as count
      FROM [DublettenReferenzmenge].[dbo].[DocumentForElasticsearch] where lastChange < dateadd(hour,-8,getdate())`;
      var query3 =`SELECT COUNT(*) as count
      FROM [DublettenReferenzmenge].[dbo].[DocumentForElasticsearch]`;
    axios.all([searchES(req,res),   test3(req,res,query),   test3(req,res,query2) , test3(req,res,query3)])
    .then(axios.spread(function (esCount, mssqlCount1, mssqlCount2, mssqlCount3) {
        totalES = esCount.hits.total;

        totalMSSQL  = mssqlCount1.recordset[0].count;
        totalMSSQL2 = mssqlCount2.recordset[0].count;
        totalMSSQL3 = mssqlCount3.recordset[0].count;totalMSSQL,  " mssqlCount2: ", totalMSSQL2, "mssqlCount3: ", totalMSSQL3);
        var msg = "ES Dokumente total: " + totalES + " MSSQL Dokumente total: " + totalMSSQL + "<br>";
        if ( totalES != totalMSSQL) {
            msg += "Critical: " + totalES != totalMSSQL + "<br>"; 
        } if ((totalES != totalMSSQL2))  {            
            msg += "Warning: " + (totalES != totalMSSQL2) + "<br>";
        } if ((totalES > totalMSSQL3))  {  
            msg += "Achtung es gibt ungelöschte Dokumente im Elasticsearch Index!";
        }      
        res.set('Content-Type', 'text/html');
        res.send(msg);
    })).catch((err) => {
        res.send(err);
    });
})

router.get("/api/test3", async function (req,res) {
    var query = `SELECT COUNT(*) as count
      FROM [DublettenReferenzmenge].[dbo].[DocumentForElasticsearch] where lastChange < dateadd(day,-1,getdate())`;
    var result = await test3(req,res,query);
    res.json(result);
})

Маршрут API / Test3 возвращает менярезультат, как обычно, но api / compareCount также возвращает мне правильные результаты ...

Кроме того, я должен использовать асинхронную функцию ... await test3 (..) синтаксическую структуру async-await дляпреобразовать мой результат в переменную ... Но мне не нужно использовать ту же структуру для моей функции api / compareCount, результат возвращается в любом случае в .then(axios.spread(function(...))).Это почему?Я в замешательстве, так как не знаю, как работают цепочки и вызовы Promise ...

РЕДАКТИРОВАТЬ: до моей функции test3 () у меня было что-то вроде этого:

async function testQuery(query) {
    try {
        let pool = await sql.connect(dbconfig);
        let result1 = await pool.request()
            //.input('input_parameter', sql.Int, value)
            .query(query);  
            sql.close();  
        return result1;      

    } catch (err) {
        console.log(err);
        sql.close();  

    } finally {
        sql.close();
    }
};

Я получил также результаты с этой функцией, однако, я получил какое-то условие гонки, когда он сказал мне, что sql-соединение уже существует, и сначала делаю sql.close (), если я перезагружаю страницу слишком быстро ...Я больше не получаю это с функцией test3 () ...

1 Ответ

0 голосов
/ 08 февраля 2019

Для начала, test3() необходимо вернуть обещание, чтобы вызывающий абонент знал, когда это было сделано и была ли ошибка или нет.Вероятно, для этого проще всего использовать async / await:

async function test3(query) => {   
    const conn = new sql.ConnectionPool(dbconfig);
    const request = new sql.Request(conn);
    await conn.connect();
    try {
        const result = await request.query(query);
        return result;
    } finally {
        conn.close();
    }
}

Различные изменения:

  1. Передавать только те аргументы, которые будут использоваться
  2. Использовать await для упрощения асинхронного логического потока
  3. Используйте команду try / finally, чтобы перехватить любую ошибку после подключения, чтобы мы всегда могли закрыть соединение и не пропускать соединение
  4. Переключиться с var на const.
  5. Создайте функцию async, чтобы она возвращала обещание, которое было подключено, когда внутреннее устройство выполнено или имеет ошибку

Затем, если вы отрегулируете, как test3() вызывается дляпередавайте только аргумент запроса (поскольку это все, что используется), ваше использование этой функции в других местах, где вы ее используете, должно работать.

Ваш код делал это:

var result = await test3(req,res,query);

Но у test3() не было возвращаемого значения, поэтому await не было ничего полезного.await работает с обещанием, и вы не возвращали обещание, которое было связано с асинхронными операциями внутри test3().Это то, что делают мои изменения выше.

...