我正在尝试反序列化一个 JSON 对象,该对象有一个
type
键,其值为字符串;如果类型是“a”,则对象类在“a.js”中定义,并且该文件包含初始化函数a_init
。可能有一个 subobjects
键,其值是对象数组。如果是这样,这些嵌套对象应该以相同的方式处理。
我的代码如下所示:
var files = [];
function load(obj) {
if (!!obj["type"]) {
let type = obj.type;
let subobjects = obj.subobjects;
let promise = new Promise(function(resolve) {
let script = document.createElement("script");
script.setAttribute("src", type + ".js");
script.addEventListener("load",resolve);
document.head.appendChild(script);
});
promise.then(function() {
if (!files.includes(type)) {
files.push(type);
if (subobjects instanceof Array) {
for (element of subobjects) {
load(element);
}
}
let func = window[type + "_init"];
if (typeof(func) =="function") {
func(obj);
}
}
});
}
}
对于这样的对象:
{ "type": "a",
"data": "foo",
"subobjects": [
{ "type": "b",
"data": "1"
}
]
}
输出为:
This is A
This is B
(功能
a_init
和b_init
仅显示一条消息用于测试目的。)
我的问题是我希望子对象在外部对象之前初始化,因此
b_init
将在 a_init
之前完成以给出以下输出:
This is B
This is A
但是当然,对
load
的嵌套调用只是创建一个新的 Promise,然后在新的 Promise 之前完成。
有什么方法可以强制同步来控制事件的顺序吗?
您应该将
load
函数转换为 async
并在其内部 await
以实现承诺以及完成递归调用。
var files = [];
async function load(obj) {
if (!!obj["type"]) {
let type = obj.type;
let subobjects = obj.subobjects;
const promise = new Promise(function(resolve) {
let script = document.createElement("script");
script.setAttribute("src", type + ".js");
script.addEventListener("load", resolve);
document.head.appendChild(script);
});
await promise;
if (!files.includes(type)) {
files.push(type);
if (subobjects instanceof Array) {
for (element of subobjects) {
await load(element);
}
}
let func = window[type + "_init"];
if (typeof(func) == "function") {
func(obj);
}
}
}
}