Javascript 在Dexie迭代中使用承诺

Javascript 在Dexie迭代中使用承诺,javascript,promise,dexie,Javascript,Promise,Dexie,我不是一个真正的承诺忍者,我知道我做错了什么。然而,我找不到我所拥有的某些特殊/类似的问题 问题是:我对IndexedDB使用了Dexie.js包装器,它是异步的。我有一个全局数据库,可以连接到其他一些dexie数据库 function handleDatabases() { var result = []; db.jobs.orderBy('title').filter(function(job) { return job.someBooleanConditi

我不是一个真正的承诺忍者,我知道我做错了什么。然而,我找不到我所拥有的某些特殊/类似的问题

问题是:我对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);
}

我已经用一种可能很奇怪的形式重写了它,但最终目标是我可以使用数组
结果
来处理一些更新。然而,由于它是异步的,所以它总是空的,直到您在控制台中检查它,在控制台中它从不为空。如何将其重写为同步

当结果仅异步可用时,不能期望返回该结果

因此,您必须始终坚持承诺(每次都返回承诺),并让您的函数也返回承诺。调用者必须使用
然后
(或
等待
,如果支持)来允许(异步)访问结果

不要将
{job:job,detail:detail}
推送到结果变量,而是返回它。它将成为
jobDetails.details.get(..)的承诺值,然后(..)
。如果您同时返回该值,您将得到一个承诺数组,然后可以使用
Promise.all

避免做出新的承诺,因为这通常会导致失败

还要避免使用在多个回调中使用的变量(如results),而不作为参数传递。相反,请尝试构造该数组并将其作为承诺值返回,这样它就可以在下一次
然后
回调中使用

以下是建议的(未测试)代码:


当结果仅异步可用时,不能期望返回该结果

因此,您必须始终坚持承诺(每次都返回承诺),并让您的函数也返回承诺。调用者必须使用
然后
(或
等待
,如果支持)来允许(异步)访问结果

不要将
{job:job,detail:detail}
推送到结果变量,而是返回它。它将成为
jobDetails.details.get(..)的承诺值,然后(..)
。如果您同时返回该值,您将得到一个承诺数组,然后可以使用
Promise.all

避免做出新的承诺,因为这通常会导致失败

还要避免使用在多个回调中使用的变量(如results),而不作为参数传递。相反,请尝试构造该数组并将其作为承诺值返回,这样它就可以在下一次
然后
回调中使用

以下是建议的(未测试)代码:


当结果仅异步可用时,不能期望返回该结果。因此,您必须始终坚持承诺(每次都返回承诺),并让您的函数也返回承诺。调用方必须使用
then
来允许(异步)访问结果。多亏了这一点,我在.each()函数中创建了一个承诺,然后使用Dexie.promise.all()调用了.then(),该函数起了作用。好的,您可能需要检查是否可以不创建(新)承诺,因为
get(…)。然后(…)
已返回承诺。很抱歉坚持,但是如果你在
中返回
{job:job,detail:detail}
,那么
回调而不是将其推到结果,它应该可以工作,没有新的承诺,不是吗?你能在问题的附录中分享你的最新版本的代码吗?这样我就可以确定,在进行调整之前,我从工作代码开始;-)当结果仅异步可用时,不能期望返回该结果。因此,您必须始终坚持承诺(每次都返回承诺),并让您的函数也返回承诺。调用方必须使用
then
来允许(异步)访问结果。多亏了这一点,我在.each()函数中创建了一个承诺,然后使用Dexie.promise.all()调用了.then(),该函数起了作用。好的,您可能需要检查是否可以不创建(新)承诺,因为
get(…)。然后(…)
已返回承诺。很抱歉坚持,但是如果你在
中返回
{job:job,detail:detail}
,那么
回调而不是将其推到结果,它应该可以工作,没有新的承诺,不是吗?你能在问题的附录中分享你的最新版本的代码吗?这样我就可以确定,在进行调整之前,我从工作代码开始;-)
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));
}