【问题标题】:Array from recursive promises returns undefined来自递归承诺的数组返回未定义
【发布时间】:2018-09-21 02:01:05
【问题描述】:

我正在使用 Jake Archibald 的 indexedDB 承诺 wrapper

我有一个对象存储,其中包含 json 对象和一个单独的自动递增键。当我检索对象时,我还需要获取密钥,以便以后删除它们。

我正在使用 iterateCursor 递归地遍历光标,这样我就可以直接将键和值添加到一个数组中,我将其作为已解决的承诺返回。

static getThings(){

    return thingsDb.then(db => {
        let keyVals = [];

        const tx = db.transaction('things');
        const unsyncedStore = tx.objectStore('things');

        return unsyncedStore.iterateCursor(cursor => {
            if(!cursor) return Promise.resolve(keyVals);
            console.log(`key: ${cursor.primaryKey}, val: ${cursor.value}`);
            keyVals.push({key: cursor.primaryKey, value: cursor.value});
            cursor.continue();
        });
    }).catch(error => {
        console.error(error);
    });

}

但是当我打电话时

DBHelper.getThings().then(returnedArray=> {
  // do something with returnedArray
})

它抛出一个错误,说返回的数组是未定义的。

【问题讨论】:

  • 函数unsyncedStore.iterateCursor返回什么?
  • 阅读您链接到的页面上的文档表明(我不确定)可能而不是 return unsyncedStore.iterateCursor(cursor => { ...您只是 unsyncedStore.iterateCursor(cursor => { 并在该块之后 return unsyncedStore.complete; -或者return unsyncedStore.complete.then(() => keyVals);
  • @JaromandaX 根据documentation,它是openCursor 的包装器,用于使用promise 迭代游标,它的工作方式相同,但需要一个回调来进行迭代而不是调用 .then()就可以了。
  • 我所做的只是查看示例中的代码,似乎unsyncedStore.complete 是一个承诺,它会在迭代完成时解决 - 当然,然后你'我想返回你建立的数组,因此 .then(() => keyVals) 所以返回的承诺解析为 keyVals - 文档没有提到 iterateCursor 实际返回的内容,如果它返回未定义,那就是问题跨度>
  • @JaromandaX 我的理解是 tx.complete 只是返回一个基于交易成功解决/拒绝的承诺,如果您的操作实际上返回了一些东西,您只需返回该承诺

标签: javascript es6-promise indexeddb


【解决方案1】:

iterateCursor 不返回任何内容(即返回未定义)

您需要返回promise 提供的unsyncedStore.complete

但是这个promise不会解析成有用的值,所以,使用.then返回keyVals

另外,if(!cursor) return Promise.resolve(keyVals); 没有意义,因为来自 iterateCursor 回调的返回值被忽略了

static getThings() {
    return thingsDb.then(db => {
        let keyVals = [];

        const tx = db.transaction('things');
        const unsyncedStore = tx.objectStore('things');
        // no return here since iterateCursor doesn't return anything useful anyway   
        unsyncedStore.iterateCursor(cursor => {
            if (!cursor) return;
            console.log(`key: ${cursor.primaryKey}, val: ${cursor.value}`);
            keyVals.push({key: cursor.primaryKey, value: cursor.value});
            cursor.continue();
        });
        // return here - complete is a promise that resolves when the iterateCursor completes
        return unsyncedStore.complete.then(() => keyVals);
    }).catch(error => {
        console.error(error);
    });
}

【讨论】:

  • 这就像一个魅力!我想我的问题是我认为 iterateCursor 的行为与常规承诺完全一样,当我有机会时,我会看到将其添加到他的文档中。
猜你喜欢
  • 1970-01-01
  • 2019-07-30
  • 1970-01-01
  • 2021-07-07
  • 2019-05-25
  • 2015-09-27
  • 2018-10-11
相关资源
最近更新 更多