【发布时间】:2018-07-11 21:10:54
【问题描述】:
我有一个将节点附加到 dom 的函数,如果节点是具有“src”属性的脚本标签,它将为“load”事件设置一个事件监听器,并且回调是相同的函数,所以当 js标签将完成执行相同的函数将被再次调用并继续在它左边的位置添加节点(使用文档片段) 伪代码示例:
function appender(){// i'm calling the function with bind so 'this' is my object
while(documentfragment.children.length > 0){
if(scriptwithsrc){
node.addeventlistener("load",appender.bind(this));
parentnode.appendchild(node);
return;
}
//if its not a script tag than just append the node
parentnode.appendchild(node);
return Promise.resolve();
现在我有了另一个函数,即执行这个函数的“主”函数。
在appender func 完成后,我正在使用“then”继续执行。
伪代码示例:
let appenderBinder = appender.bind(Myobject);
Myobject.fragment = fragment1;
appenderBinder().then(() => {
//first execution for fragment1 is over lets continue to fragment2
//we call it again but change our object before that
Myobject.fragment = fragment2;
appenderBinder().then(() => {
//some more code
})})
问题在于,如果片段包含带有 src 的脚本标记,则该函数只会返回;并且不返回承诺,所以我得到了
"Cannot read property 'then' of undefined",
但是我需要使用 return 来退出函数并等待回调再次执行它并继续从同一个位置追加,并且只有在它完成追加每个节点之后,promise 才会返回并且 ".then ()”应该被执行。 有什么想法吗?
【问题讨论】:
-
我认为您在这里所做的不是处理此问题的合适方法。它是可以修复的,但即使修复它也不是处理这个问题的正确方法。要解决此问题,您还需要在有脚本时返回一个承诺,但您需要返回和未解决的承诺,然后一旦加载事件触发,它就会“解决”。在此处阅读有关如何执行此操作的更多信息:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
-
@Dellirium 首先非常感谢您的回复,确实我可以创建一个promise并使用promise.all在所有promise返回并且函数完成附加所有内容时返回,但是当遇到脚本标签时我在继续追加之前需要等待加载事件触发,我只是看不到如何实现这一点,因为我需要等待前一个承诺在继续之前解决,而不是在所有承诺解决后返回 promise.all 到 main函数
-
让我确认我理解正确,假设您有一个处理片段 A、B、C 和 D 的承诺链,假设片段 B 有一个脚本标签。这个标签被加载,加载后你想简单地继续到 C 和 D 上,或者你想做其他事情,比如,idk 加载一个不在初始链中的 X?
-
@Dellirium 让我详细解释一下:假设我有一个有 10 个节点的片段,所以“附加器”开始附加每个节点(我们需要保持顺序,这对于 js 标签至关重要) 我们遇到一个 js 标签,所以我们绑定到 load 事件,此时我们需要等待 js 执行和 load 事件触发,这样我们才能继续附加节点
-
我在下面添加了一个带有解释的答案,但是,请注意您在代码中使用了
while并且没有关闭帖子中的 while 标记。正是由于这个原因,我没有为“引用”代码的while部分而烦恼,但从逻辑上讲,它必须在执行常规return Promise.all()之前关闭它的块,我认为这是这里的目标
标签: javascript html asynchronous promise