简体   繁体   English

等待节点js中的sqlite3查询

[英]wait for sqlite3 query in node js

I am creating an array JSONs with some test names and questions that are fetched from a database as follows:我正在创建一个数组 JSON,其中包含一些从数据库中获取的测试名称和问题,如下所示:

db.all(sql_instruction, [], (err, rows) => {
        if (err) {
            console.log(err)
        }

        rows.forEach(test=>{
            let test_name = test.test_name;
            let question_array = [];
            sql_instruction = `SELECT * from questions where test_id = ?`;
            db.all(sql_instruction, [test.id], (err, rows) => {
                if (err) {
                    console.log(err);
                }
                rows.forEach(question=> {
                    question_array.push(question);
                });
                test_array.push(JSON.stringify({'test_name':test_name, questions:question_array}));
            });
        });
    });

If I try to access the variable 'test_array' outside the first db.all(), I would get an empty array because the async nature of the function.如果我尝试访问第一个 db.all() 之外的变量“test_array”,我会得到一个空数组,因为 function 的异步特性。

What would be the best way to 'wait' for the completion of the 'test_array' variable to use it further in the application? “等待”完成“test_array”变量以在应用程序中进一步使用它的最佳方法是什么?

We can use Promise and async/await sugar syntax to make an asynchronous code looks like synchronous one.我们可以使用 Promise 和 async/await 糖语法使异步代码看起来像同步代码。 In the code below, I create a function getAllPromise to wrap the db.all method in a Promise.在下面的代码中,我创建了一个 function getAllPromise以将db.all方法包装在 Promise 中。 Then I can "wait" my getAllPromise function.然后我可以“等待”我的getAllPromise function。

function getAllPromise(query, params) {
    return new Promise((resolve, reject) => {

        db.all(query, params, (err, rows) => {

            if(err) {
                
                // case error
                reject(err);
            }

            // "return" the result when the action finish
            resolve(rows);
        })
    })
}

async function getTestWithQuestions() { // your code

    try {
        let sql_instruction = ""; // your SQL query;
        const rows = await getAllPromise(sql_instruction, []);
        let test_array = [];

        for(let i = 0; i < rows.length; i = i + 1) {

            const test = rows[i];
            let test_name = test.test_name;
            let question_array = [];
            sql_instruction = `SELECT * from questions where test_id = ?`;

            const question_rows = await getAllPromise(sql_instruction, [test.id]);
            question_rows.forEach(question=> {
                question_array.push(question);
            });

            test_array.push(JSON.stringify({'test_name':test_name, questions:question_array}))
        }

        return test_array;

    } catch(error) {
        console.log(error);
        throw error;
    }
}

// using
// you need to add the keyword "async" in the function that call getTestWithQuestions, then :

const testWithQuestions = await  getTestWithQuestions(); // testWithQuetions is `test_array`

// if you don't want to add async keyword, then : 
getTestWithQuestions()
.then(testWithQuestions => console.log(testWithQuestions))
.catch(error => console.log(error));

You can find more information about callback, Promise and async/await here您可以在此处找到有关回调、Promise 和 async/await 的更多信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM