在 Dexie 迭代中使用 Promise
Using a Promise inside a Dexie iteration
我不是一个真正的无极忍者,我知道我做错了什么。但是我找不到我所拥有的 particular/simular 问题。
问题:我对异步的 IndexedDB 使用 Dexie.js 包装器。我有一个全局数据库,它通向其他一些 dexie 数据库。
function handleDatabases() {
var result = [];
db.jobs.orderBy('title').filter(function(job) {
return job.someBooleanCondition;
}).each(function(job, cursor) {
let jobDetails = new Dexie(job.correspondingDB);
jobDetails.version(1).stores({
details: 'key,value1,value2'
});
jobDetails.details.get(someKey).then(function(detail) {
result.push({job: job, detail: detail});
})
}).catch(function(error) {
console.log(error);
});
handleResult(result);
}
我已经用一种可能很奇怪的形式为 SO 重写了它,但最终目标是我可以使用数组 result
来处理一些更新。但是,由于它是异步的,因此它始终为空,直到您在控制台中检查它时它永远不会为空。我怎样才能将其重写为同步的?
当结果仅异步可用时,您不能指望 return 结果。
所以你必须一直坚持 promise(return 每次都这样做),让你的函数也 return 一个 promise。调用者必须使用 then
(或 await
,如果支持)以允许(异步)访问结果。
不是将 {job: job, detail: detail}
推送到 results 变量,而是 return 它。它将成为 jobDetails.details.get(..).then(..)
的承诺值。如果你 return 也是,你将有一系列承诺,然后可以用 Promise.all
解决
避免创建新的 Promise,因为这通常会导致 promise constructor antipattern。
同时避免使用在多个回调中使用但未作为参数传递的变量(如 results)。相反,尝试构建 return 该数组作为承诺值,以便它可以在下一个 then
回调中使用。
这是建议的(未经测试的)代码:
function handleDatabases() {
db.jobs
.orderBy('title')
.filter(job => job.someBooleanCondition)
.toArray(jobs =>
jobs.map(job => {
let jobDetails = new Dexie(job.correspondingDB);
jobDetails.version(1).stores({
details: 'key,value1,value2'
});
return jobDetails.details.get(someKey)
.then(detail => ({job: job, detail: detail}))
}) // is returned
)
.then(result => Promise.all(result))
.then(handleResult)
.catch(error => console.log(error));
}
我不是一个真正的无极忍者,我知道我做错了什么。但是我找不到我所拥有的 particular/simular 问题。
问题:我对异步的 IndexedDB 使用 Dexie.js 包装器。我有一个全局数据库,它通向其他一些 dexie 数据库。
function handleDatabases() {
var result = [];
db.jobs.orderBy('title').filter(function(job) {
return job.someBooleanCondition;
}).each(function(job, cursor) {
let jobDetails = new Dexie(job.correspondingDB);
jobDetails.version(1).stores({
details: 'key,value1,value2'
});
jobDetails.details.get(someKey).then(function(detail) {
result.push({job: job, detail: detail});
})
}).catch(function(error) {
console.log(error);
});
handleResult(result);
}
我已经用一种可能很奇怪的形式为 SO 重写了它,但最终目标是我可以使用数组 result
来处理一些更新。但是,由于它是异步的,因此它始终为空,直到您在控制台中检查它时它永远不会为空。我怎样才能将其重写为同步的?
当结果仅异步可用时,您不能指望 return 结果。
所以你必须一直坚持 promise(return 每次都这样做),让你的函数也 return 一个 promise。调用者必须使用 then
(或 await
,如果支持)以允许(异步)访问结果。
不是将 {job: job, detail: detail}
推送到 results 变量,而是 return 它。它将成为 jobDetails.details.get(..).then(..)
的承诺值。如果你 return 也是,你将有一系列承诺,然后可以用 Promise.all
避免创建新的 Promise,因为这通常会导致 promise constructor antipattern。
同时避免使用在多个回调中使用但未作为参数传递的变量(如 results)。相反,尝试构建 return 该数组作为承诺值,以便它可以在下一个 then
回调中使用。
这是建议的(未经测试的)代码:
function handleDatabases() {
db.jobs
.orderBy('title')
.filter(job => job.someBooleanCondition)
.toArray(jobs =>
jobs.map(job => {
let jobDetails = new Dexie(job.correspondingDB);
jobDetails.version(1).stores({
details: 'key,value1,value2'
});
return jobDetails.details.get(someKey)
.then(detail => ({job: job, detail: detail}))
}) // is returned
)
.then(result => Promise.all(result))
.then(handleResult)
.catch(error => console.log(error));
}