SQLite 从插件中的 SQLITE 数据库中读取
SQLite read from SQLITE database in plugin
我需要从我的插件中的 SQLite 数据库中读取值。为此,我找到了 sqlite.jsm
模块。我的问题是我想将一行作为全局变量,但是 SQLite(承诺和任务)中使用的代码是异步的。有什么方法可以将我的数据库中的信息收集到全局变量中吗?
let iDs = [];
Task.spawn(function* () {
let db = yield Sqlite.openConnection({ path:
permissionFilePath});
try {
let row = yield db.execute(
"SELECT id FROM 'moz_hosts'");
for ( i=0; i < row.length; i++) {
console.log("row["+ i +"] :" +
row[i].getResultByIndex(0));
yield iDs.push(row[i].getResultByIndex(0));
}
}
finally {
yield db.close();
}
});
// Part of the code that doesn't work, because IDs are not yet assigned any values!
console.log("debug");
for (i=0; i<iDs.length; i++) {
yield console.log("iDs ["+i+"] = "+ iDs[i]);
}
首先,对于一个 Task,你只需要产生 return 承诺的东西,因此 运行 是异步的。不需要yield iDs.push(row[i].getResultByIndex(0));
,因为push操作会同步return数组的新长度。不过,这对于代码本身来说应该不是什么大问题。
你真的需要 id 是全局的吗?也许你可以重构你的代码,这样你就不需要全局保存它们了。
如果这不是一个选项,您将必须阻止所有将要访问 ID 的操作,直到 SQL 调用完成。您可以依靠 Task.spawn() 本身也会 return 一个承诺这一事实来做到这一点。这也有很好的副作用,你不需要额外的全局数组:
let idsPromise = Task.spawn(function*() {
let ids = [];
let db = yield Sqlite.openConnection({ path: permissionFilePath});
try {
let row = yield db.execute("SELECT id FROM 'moz_hosts'");
for (let i = 0, len = row.length; i < len; i++) {
ids.push(row[i].getResultByIndex(0));
}
// Instead of the loop you can also use:
// ids = row.map(row => row.getResultByIndex(0));
} finally {
yield db.close();
}
return ids;
});
然后,在代码的其他部分,当您需要 id 时,您可以使用:
idsPromise.then(function(ids) {
// Do something with ids
});
或者,您也可以在任务中获取它们:
Task.spawn(function*() {
let ids = yield idsPromise;
});
您可以多次执行此操作。一旦承诺得到解决,then()
部分将尽快执行。
我需要从我的插件中的 SQLite 数据库中读取值。为此,我找到了 sqlite.jsm
模块。我的问题是我想将一行作为全局变量,但是 SQLite(承诺和任务)中使用的代码是异步的。有什么方法可以将我的数据库中的信息收集到全局变量中吗?
let iDs = [];
Task.spawn(function* () {
let db = yield Sqlite.openConnection({ path:
permissionFilePath});
try {
let row = yield db.execute(
"SELECT id FROM 'moz_hosts'");
for ( i=0; i < row.length; i++) {
console.log("row["+ i +"] :" +
row[i].getResultByIndex(0));
yield iDs.push(row[i].getResultByIndex(0));
}
}
finally {
yield db.close();
}
});
// Part of the code that doesn't work, because IDs are not yet assigned any values!
console.log("debug");
for (i=0; i<iDs.length; i++) {
yield console.log("iDs ["+i+"] = "+ iDs[i]);
}
首先,对于一个 Task,你只需要产生 return 承诺的东西,因此 运行 是异步的。不需要yield iDs.push(row[i].getResultByIndex(0));
,因为push操作会同步return数组的新长度。不过,这对于代码本身来说应该不是什么大问题。
你真的需要 id 是全局的吗?也许你可以重构你的代码,这样你就不需要全局保存它们了。
如果这不是一个选项,您将必须阻止所有将要访问 ID 的操作,直到 SQL 调用完成。您可以依靠 Task.spawn() 本身也会 return 一个承诺这一事实来做到这一点。这也有很好的副作用,你不需要额外的全局数组:
let idsPromise = Task.spawn(function*() {
let ids = [];
let db = yield Sqlite.openConnection({ path: permissionFilePath});
try {
let row = yield db.execute("SELECT id FROM 'moz_hosts'");
for (let i = 0, len = row.length; i < len; i++) {
ids.push(row[i].getResultByIndex(0));
}
// Instead of the loop you can also use:
// ids = row.map(row => row.getResultByIndex(0));
} finally {
yield db.close();
}
return ids;
});
然后,在代码的其他部分,当您需要 id 时,您可以使用:
idsPromise.then(function(ids) {
// Do something with ids
});
或者,您也可以在任务中获取它们:
Task.spawn(function*() {
let ids = yield idsPromise;
});
您可以多次执行此操作。一旦承诺得到解决,then()
部分将尽快执行。