Heim  >  Fragen und Antworten  >  Hauptteil

NodeJS Promise gibt unter zufälligen Umständen einen undefinierten Wert zurück

Zuallererst tut es mir leid, wenn es auf diese Frage bereits eine Antwort gibt, aber ich habe nach solchen Fragen gesucht und nichts Nützliches gefunden.

Ich entwickle eine NodeJS-Anwendung, die das MySQL-NPM-Paket zum Abfragen einer Datenbank verwendet. Ich habe mehrere Abfragen geschrieben, die mit Hilfe von Versprechen gut funktionieren (denn so funktioniert das SQL-Modul). Ich habe kein Problem, wenn die Abfrageprozedurfunktion get_works (unten definiert) normal aufgerufen wird. Wenn ich diese prozedurale Funktion jedoch im Express Router aufrufe, erhalte ich ein seltsames Verhalten.

view.get("/works", (req, res) => {
    (async () => {
        res.json(await get_works());
    })()
});

async function get_works(offset=0,limit=6){

    let cdc_database = mysql.createConnection({
        /*Filled with credentials*/
    });
    
    const get_texts = `SELECT TEXID,TXNOM,TXRES FROM TEXTE LIMIT ${limit} OFFSET ${offset};`; // Valid request

    /*Two steps: get texts and get authors of each texts*/

    cdc_database.connect();
    const texts = await database_promise_query(cdc_database, get_texts);
    /*This await always have a correct output*/

    let text_authors = [];

    for(i = 0; i < texts.length; i++){

        get_text_authors = `SELECT AUPRE, AUNOM FROM AUTEURS,ECRIT_PAR\
        WHERE AUTEURS.AUTID=ECRIT_PAR.AUTID AND TEXID=${texts[i].TEXID};`; // Request is valid

        text_authors[i] = (await database_promise_query(cdc_database, get_text_authors));
        /*          ^^^^^^^^
        The await above returns an undefined value randomly when called through the router
        */
        if(text_authors[i] === undefined){
            console.error(`[get_works] - Server error on ${i}th text's authors`)
            text_authors[i] = [{AUPRE: "Prénom", AUNOM: "Nom"}]
        }

    }
    

    cdc_database.end();

    return works_to_JSON(texts, text_authors)
}

Manchmal hat eine Abfrage an die Datenbank keine undefinierten Werte, aber sobald es einen undefinierten Wert gibt, sind auch alle nachfolgenden Werte undefiniert.

Example trace log

(1st call, 3 errors)
[
  [ RowDataPacket { AUPRE: 'xxx', AUNOM: 'xxx' } ],
  [ RowDataPacket { AUPRE: 'xxx', AUNOM: "xxx" } ],
  [ RowDataPacket { AUPRE: 'xxx', AUNOM: 'xxx' } ],
  [ { AUPRE: 'Prénom', AUNOM: 'Nom' } ],
  [ { AUPRE: 'Prénom', AUNOM: 'Nom' } ],
  [ { AUPRE: 'Prénom', AUNOM: 'Nom' } ]
]

(2nd call, no error)
[
  [ RowDataPacket { AUPRE: 'xxx', AUNOM: 'xxx' } ],
  [ RowDataPacket { AUPRE: 'xxx', AUNOM: "xxx" } ],
  [ RowDataPacket { AUPRE: 'xxx', AUNOM: 'xxx' } ],
  [ RowDataPacket { AUPRE: 'xxx', AUNOM: 'xxx' } ],
  [ RowDataPacket { AUPRE: 'xxx', AUNOM: "xxx" } ],
  [ RowDataPacket { AUPRE: 'xxx', AUNOM: 'xxx' } ],
]

Das ist mein Versprechenspapier:

function database_promise_query(database, query){
    return new Promise(res => {
        database.query(query, (error, results, fields) => {
            if(error) {res(undefined); console.log(error)}
            res(results);
        })
    })
}

Der Aufruf dieser Funktion außerhalb des Routers funktioniert jedoch einwandfrei:

(async () => {
    await get_works(0, 10);
    await get_works(10, 10);
    await get_works(20, 10);
    await get_works(30, 10);
})()

Habe ich etwas verpasst? Ich denke, dass alle Abfragen korrekt sind, da ich die gewünschten Ergebnisse erhalten kann. Das Problem liegt möglicherweise an meiner asynchronen/wartenden Behandlung. Vielen Dank für all die Hilfe, die Sie leisten können.

Bearbeiten 1

Basierend auf dem Vorschlag von @tromgy habe ich die Versprechensverpackung umgeschrieben.

function database_promise_query(database, query){
    return new Promise((res, rej) => {
        database.query(query, (error, results, fields) => {
            if(error) {rej(error); throw new Error(error)}
            console.log("Received response", results)
            res(results);
        })
    })
}

Die Ablehnung erfolgt jedoch nie (was sinnvoll ist, da in der Datenbank keine passenden Daten vorhanden sind). Um die Protokolle zu bereinigen, habe ich einen anderen Router für ähnliche Anfragen über eine andere Datenbankverbindung deaktiviert. Durch das Entfernen dieses Routers wurde der Fehler ebenfalls behoben. Ich weiß nicht, wie das möglich ist (vielleicht ist eine Variable global deklariert, also würde ich nach einem solchen Problem suchen).

P粉321584263P粉321584263277 Tage vor373

Antworte allen(1)Ich werde antworten

  • P粉063862561

    P粉0638625612024-01-17 09:49:18

    如图所示,问题是一个共享的循环计数器。我的一个同事在迭代之前忘记添加 let 关键字,所以 for 循环跳跃了数值。

    我现在讨厌这个 JavaScript 特性。谢谢帮助!

    Antwort
    0
  • StornierenAntwort