【问题标题】:Using a Promise inside a Dexie iteration [duplicate]在 Dexie 迭代中使用 Promise [重复]
【发布时间】:2017-08-27 00:34:21
【问题描述】:

我并不是一个真正的 Promise Ninja,我知道我做错了什么。但是我找不到我所遇到的一些特殊/相似的问题。

问题:我为 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 来处理一些更新。但是,由于它是异步的,因此它始终为空,直到您在控制台中检查它,它永远不会为空。如何将其重写为同步?

【问题讨论】:

  • 当结果仅异步可用时,您不能期望返回结果。所以你必须一直坚持承诺(每次返回它们),并且让你的函数也返回一个承诺。调用者必须使用then 允许(异步)访问结果。
  • 好的,您可能想检查是否可以不创建(新)承诺,因为get(...).then(...) 已经返回了承诺。所以就退回那个。
  • 抱歉坚持,但如果你在then 回调中返回{job: job, detail: detail} 而不是将其推送到result,它应该可以在没有新承诺的情况下工作,不是吗?
  • 您能否在问题的附录中分享您最新版本的代码?然后我确定我从工作代码开始,然后再进行调整;-)

标签: javascript promise dexie


【解决方案1】:

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

所以你必须一直坚持承诺(每次都返回它们),并且让你的函数也返回一个承诺。调用者必须使用then(或await,如果支持)允许(异步)访问结果。

不要将{job: job, detail: detail} 推送到results 变量,而是返回它。它将成为jobDetails.details.get(..).then(..) 的承诺值。如果你也返回那个,你会得到一个 promise 数组,然后可以用 Promise.all 解决。

避免创建新的 Promise,因为这通常会导致 promise constructor antipattern

同时避免使用在多个回调中使用但未作为参数传递的变量(如 results)。而是尝试构造该数组并将其作为承诺值返回,以便在下一个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));
}

【讨论】:

    猜你喜欢
    • 2019-07-26
    • 2017-05-24
    • 2018-02-24
    • 1970-01-01
    • 2016-10-21
    • 1970-01-01
    • 1970-01-01
    • 2014-06-27
    • 2017-12-17
    相关资源
    最近更新 更多