JavaScript 函数访问 SQLite 数据库

JavaScript functions accessing SQLite db

我将 Electron 与 JavaScript 一起使用,并试图访问 SQLite 数据库。数据库的输出是国家列表。目标是 div 中的一个简单 ul。该操作由附加到页面上按钮的 onclick 事件调用。

问题来了。从技术上讲,我可以访问数据库。但是,在数据层 (data.js) 中,我有两个选项只能用于从 db 文件填充数组。每个中的 console.log() 仅用于调试。

在选项 1 中,return 元素 return 是一个长度为 23 的数组(请参见下图的选项 1),同时将 return 元素移出db.all 函数 returns 数组顶部为空,但在扩展长度为 0 时填充(参见选项 2 图像)。我认为第一个选项是数组的外观,但是因为数组包含在 db.all 函数中,所以它不会 return data.js 中的 getLocations() 任何东西。随后,model.js 和 view.js 中的数组(下面的代码)保持未定义状态。

如果我选择选项 2,数组将填充到线下(即数据、模型和视图),但所有数组的长度都保持为 0,因为它们是 "empty on top"。因此,遍历数组以写入 div 失败,因为长度最终不正确,为 0.

附带说明一下,如果我将国家/地区硬编码到 data.js 中的数组中,一切正常并且国家/地区列表写入页面。虽然我可以(并且需要)从 db 文件中获取数据,但它似乎会导致上述问题。所以,这真的是关于 data.js 如何 return 数组。

有没有人对如何正确地正确填充数组有任何建议,以便我可以遍历它们并写入页面?

感谢您的帮助!!


Data.js 选项 1:

function getLocations() {
    var sqlite3 = require('sqlite3').verbose();
    var file = 'db/locations.sqlite3';
    var db = new sqlite3.Database(file);
    var larray = [];

    db.all('SELECT * FROM Country', function(err, rows) {
        rows.forEach(function(row) {
            larray.push(row.CountryName);
        })
    console.log(larray);
    return larray;
    });
}

Data.js 选项 2:

function getLocations() {
    var sqlite3 = require('sqlite3').verbose();
    var file = 'db/locations.sqlite3';
    var db = new sqlite3.Database(file);
    var larray = [];

    db.all('SELECT * FROM Country', function(err, rows) {
        rows.forEach(function(row) {
            larray.push(row.CountryName);
        })
    });
    console.log(larray);
    return larray;  
}

选项 1 图片:

选项 2 图片:

model.js:

function Locations() {

    //Pull location values from data
    var viewLoc =  getLocations();

    return viewLoc;
}

view.js:

function viewLocation() {

    var viewLoc = Locations();

    var container = document.getElementById('wrapper');

    for (var i=0; i < viewLoc.length; i++) {  
      container.insertAdjacentHTML('beforeend', '<li>' + viewLoc[i]);
    }
};

db.all 是一个异步函数。在从您的数据库收到响应之前,它的回调函数不会立即执行。

选项 1 的代码中发生的事情是它将调用 db.all 函数,并且由于它是异步的,它将移至下一行 - 即您的 console.log 和最后 return larray 将是空的。

解决您的问题;你需要让 getLocations() 接受一个回调函数作为参数。然后当收到来自 db.all 的响应时,通过回调填充 larray 和 return。

示例:

data.js

function getLocations(done) {
    var sqlite3 = require('sqlite3').verbose();
    var file = 'db/locations.sqlite3';
    var db = new sqlite3.Database(file);
    var larray = [];

    db.all('SELECT * FROM Country', function(err, rows) {
        // This code only gets called when the database returns with a response.
        rows.forEach(function(row) {
            larray.push(row.CountryName);
        })
        return done(larray);
    });
}

model.js

function Locations(done) {
    return getLocations(done);
}

view.js

function viewLocation() {
    // Pull location values from data
    var viewLoc =  Locations(function(/*OOPS, THIS WAS MISSING!!=*/results) {
        // Code only gets triggered when getLocation() calls return done(...); 
        var container = document.getElementById('wrapper');

        for (var i=0; i < results.length; i++) {  
            container.insertAdjacentHTML('beforeend', '<li>' + results[i]);
        }
    });
}

顺便说一句,再次查看您的代码。似乎 viewLocation() 期待 return 从 Location() 编辑某些东西,但从你的代码来看,它目前没有 returning 任何东西,但我怀疑它可能只是你试图调试东西。无论如何,这超出了问题范围,所以我不会太在意这里。