gpt4 book ai didi

javascript - 从客户端调用生成器函数,该函数使用 Promises 在循环中执行异步调用

转载 作者:行者123 更新时间:2023-11-28 04:17:42 24 4
gpt4 key购买 nike

我需要从上到下抓取整个 DOM 来处理每个节点。当一个节点满足某些条件时,我需要同步处理有关该节点的信息,这意味着在处理工作完成之前我不会继续处理 DOM 中的下一个节点。

节点的处理涉及多个ajax调用,我想异步执行这些调用。只有当所有的ajax调用完成后,才能完成最后的处理工作,并将结果返回到我的DOM抓取中的点。

我倾向于的解决方案是创建一个生成器函数,它会抓取 DOM,然后在满足条件的节点时执行yield 语句,并将该节点的内容传输回客户端(通过yield语句)调用下一个函数。

发起对生成器函数的调用的客户端将解析节点的数据,创建多个 Promise 并使用 Promise.all() 异步执行所有这些 Promise。

一旦所有的 Promise 完成并且处理完成,生成器函数就会再次被调用,但是这次来自客户端的处理后的数据将返回到 Yield 语句停止的位置,然后将其合并回 DOM。

我不清楚的是如何创建执行节点处理(包括执行 promise )的客户端代码。如果可能的话,我想避免递归调用客户端函数。这是我可以想象的一些伪代码:

生成器:

function *crawlDOM() {
let node = "html";

function processNode(node) {
if (node.value == "someCriteria") {
let processedValue = yield node.value;
// Do something with the processed value...
}

for (let i = 0; i < node.children.length; i++) {
processNode(node.children[i]);
}
}
}

节点处理客户端:

function processNodeData() {
var crawler = crawlDOM();
var processedData = "";

while (true) {
var nodeData = crawler.next(processedData).value;
var items[] = nodeData.split("\n");
var promises[] = [items.length];

for (let i = 0; i < items.length; i++) {
promises[i] = new Promise(function (resolve, reject) {
// Do some work
resolve(result);
}
}

Promises.all(promises)
.then(function(result) {
processedData = "some new data";
// Do some final processing.
// At this point, we need to call the generator function again but with the processed data.
// But this is the wrong place to do it because the "while" loop will have already moved on
// to the next node while this "then" code is being executed.
})

}
}

如何解决循环问题,以便下次调用生成器函数仅在 Promise.all() 完成后发生?

最佳答案

在循环中执行 Promise 的关键是将这些 Promise 放入异步函数中:

function processNode(x) {
return new Promise(resolve => {
setTimeout(() => {
resolve(x);
}, 2000);
});
}

async function startNodeProcessing() {
while(true) {
var a = processNode(20);
var b = processNode(30);
var r = await a + await b;
}

return;
}
startNodeProcessing();

代码行:

var r = await a + await b;

阻塞,直到所有 promise 完成。这意味着您不需要 Promise.all,尽管您可能仍然可以使用它。阻塞完成后,您可以继续重复循环。没有递归调用,并且阻塞是异步函数 native 的,这意味着您不会阻塞主线程,因此如果循环中有冗长的代码需要处理,您不会看到任何 UI 问题。

关于javascript - 从客户端调用生成器函数,该函数使用 Promises 在循环中执行异步调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45688946/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com