使用 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)
我正在尝试执行树结构的 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)