【问题标题】:How to wait for database to finish querying before returning a response?如何在返回响应之前等待数据库完成查询?
【发布时间】:2017-10-12 04:19:09
【问题描述】:

我正在制作一个与本地数据库密切合作的 React 和 Electron 应用程序。我有 2 个表,“已阻止”和“未阻止”,此应用程序的目标是通过单击按钮将一行数据从一个表移动到另一个表。大多数事情似乎都运行良好,但我无法使用 redux 数据异步更新我的表。这是我必须获取数据的函数:

var fetchDBData = (tablename) => {
  var db = new sqlite3.Database('processlist.db');
  var queries = [];
  db.each("SELECT * FROM " + tablename, function(err, row) {
    queries.push(row);
  });

  db.close();
  return queries;
};

我有 2 个更新 redux 的操作:

export function updateBlockedFiles(blacklist_queries) {
  console.log(blacklist_queries);
  return {
    type: UPDATE_BLOCKED_FILES,
    payload: blacklist_queries
  }
};

export function updateWhitelistedFiles(whitelist_queries) {
    console.log(whitelist_queries);
    return {
        type: UPDATE_WHITELISTED_FILES,
        payload: whitelist_queries
    }
};

我在组件中的调用如下所示:

unblockProcess(id) {
    window.transferRowFromTable('blacklistdb', 'whitelistdb', id);
    var blacklist_queries = window.fetchDBData('blacklistdb');
    var whitelist_queries = window.fetchDBData('whitelistdb');
    this.props.updateBlockedFiles(blacklist_queries);
    this.props.updateWhitelistedFiles(whitelist_queries);
};

我发现的问题主要发生在 fetchDBData() 中。当我调用 this.props.updateBlockedFiles() 时,它会返回一个空的查询数组而不是填充的数组。我认为这可能是一个异步问题,但我不确定如何解决它。我已经看到了使用 Promise 的想法,但我不知道如何将它与 React 集成。任何帮助都会有所帮助!

【问题讨论】:

  • 您实际在哪里执行查询?我认为您需要一个 db.run() 电话或类似电话 - 我不知道确切的语法。
  • 在 db.each() 查询中,我将每一行附加到查询 var,它之所以有效,是因为我在启动时调用了此函数并且表已正确填充,只有当我更新并调用它时再次返回一个空数组。

标签: javascript sqlite reactjs asynchronous electron


【解决方案1】:

我正在做类似的事情......让我画出这个概念,看看它是否有意义。

在将您的 IPC 请求发送到主进程以运行 SQL 之前,在您的渲染器进程中创建一个 IPC 侦听器以在 SQL 查询完成时充当回调。可以构造此回调来处理 SQLite 查询的数据输出。下面的粗略示例:

渲染进程:

var ipcRenderer = require('electron').ipcRenderer    

function handleDBResponse(event, data){
   // Do something with the data
}

ipcRenderer.on('dbResponse', handleDBResponse)

ipcRenderer.send('dbQuery', "some_table_name")

主进程:

var ipcMain = require('electron').ipcMain

function doDBQuery(event, tablename){
    // Perform your DB query via SQLite

    var db = new sqlite3.Database('processlist.db');
    var queries = [];
    db.each("SELECT * FROM " + tablename, function(err, row) {
      queries.push(row);
    });

    db.close();
    // Send queries back to callback handler
    event.sender.send('dbResponse', queries)
}

ipcMain.on('dbQuery', doDBQuery)

这都是通过 Electron 的 IPC 方法在主进程和渲染器进程之间进行通信的。更多细节可以在这里研究:https://github.com/electron/electron/blob/master/docs/api/ipc-main.md

【讨论】:

  • 感谢您的解释,但是,我没有使用任何 ipcMain 或 ipcRenderer 方法。我将这些 javascript 函数编码在一个文件中,并作为脚本包含在我的 index.html 中,并在我的 React 组件中运行它们。
  • 同样的原则也适用——在你 db.close() 调用回调函数而不是 event.sender.send(即上面示例中的 handleDbBesponse())将数据推送到 Redux 或任何你需要的地方之后它。
  • 要保持fetchDBData() 函数的纯净,向函数添加callback 参数并在return 之前调用该回调...
  • 你能给我举个例子吗?我对回调函数不是很熟悉。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-17
  • 2019-03-03
  • 2018-06-07
  • 1970-01-01
  • 2018-05-07
  • 2015-09-22
相关资源
最近更新 更多