使用 chrome.storage.sync 时未按正确顺序遍历树

Tree not being traversed in correct order when using chrome.storage.sync

我正在尝试执行树结构的 DFS 遍历,存储为映射 Root_Node_Value -> Array_of_Children。当我尝试执行遍历时,将映射存储为普通对象,树按预期遍历。

// Correct DFS 
treeMapping = {'1221':['1223','1224']}

function closeTree(root) {
    const children = treeMapping[root] || [];
    children.forEach(function (child) { closeTree(child) });

    console.log("Closing: "+root);
}

以上代码的输出,如预期,是:1223, 1224, 1221

但是,当我尝试实现相同的逻辑时,使用 chrome.storage.sync 检索映射,却没有遵循预期的顺序。

// Incorrect DFS
function closeTree(root) {

  chrome.storage.sync.get(root.toString(), data => {
    const children = data[root] || [];
    children.forEach(function(child) { closeTree(child); });

    console.log("Closing: "+root);
  });
}

使用 chrome.storage.sync 的代码输出 1221, 1222, 1226,即使存储在存储器中的树映射是相同的。这显然是不正确的,因为根值 1221 应该最后打印。

// Retrieved value using chrome.storage.get('1221', ...)
{1221: Array(2)}
    1221: (2) [1222, 1226]

此行为的原因是什么,我该如何解决?

chrome API 是异步的。一个简单的经验法则是,如果该方法根据文档接受回调,那么它会异步运行。

最简单的解决方案是 promisify closeTree 并在 children 上使用 Promise.all:

function closeTree(root) {
  return new Promise(resolve => {
    chrome.storage.sync.get(root.toString(), async data => {
      const children = data[root] || [];
      await Promise.all(children.map(closeTree));
      resolve();
    });
  });
}

P.S。您可以通过一次操作读取所有 children 来进行相当大的优化:
chrome.storage.sync.get(children, processAllChildren)