所以我一直在努力思考一个可能的解决方案,但我试图找出一个简单的例子却没有成功。
所以我有一组看起来像这样的数据:
const arr = [{
"content": "FIRST_CONTENT_HERE",
"callback": function callback () {}
},
{
"content": "SECOND_CONTENT_HERE",
"callback": function callback () {}
},
{
"content": "THIRD_CONTENT_HERE",
"callback": function callback () {}
},
{
"content": "THIRD_CONTENT_HERE",
"callback": function callback () {}
}
];
我想创建一个生成器来遍历该数组但不返回(yield?)控制返回到下一次迭代,直到该回调函数被执行。我尝试将该回调包装在一个 promise 中,这样在执行该回调之前该 promise 不会解决。我试着确保回调是一个异步函数来包装那个承诺。我尝试了一些东西,但我就是无法让它们工作。在我调用生成器函数并遍历它之后,它只是遍历了数组的每个元素。无论我如何设置循环,它都不会在进入下一次迭代之前等待回调执行。
我四处搜索,但我发现的大多数关于生成器的例子以及它们如何与承诺(或异步函数)交互,这些例子只显示了这样的东西
yield Promise.resolve(x)
,这不是我想要的。我不希望它立即解决——我需要它等到 callback
被执行。并且回调将设置为 onclick 处理程序(以关闭对话框)并且仅在该事件发生时执行。所以基本上,在前一个对话框关闭之前,下一个对话框不应该实例化。
我如何最好地实现我想要实现的功能?正如我所说,我只是无法理解这个……
这是我写的一些代码的例子。当我尝试不同的事情时,这经历了几次变化。我在这里使用 fetch() 是因为我知道它会返回一个 Promise。我确信 Promises 需要在我的解决方案中的某个地方出现,以确保我的非异步
callback()
在控制继续之前执行。这很糟糕,但我只是在尝试不同的概念证明。
async function runRequest(url) {
const response = await fetch(url);
return response;
}
async function* setupGenerator(arr) {
for (let i = 0; i < arr.length; i++) {
const response = await runRequest(arr[i]);
yield response;
}
}
const urls = [
'/activityViewer/index.html',
'/message/index.html',
'/users/index.html',
];
debugger;
const generator = setupGenerator(urls);
for (let response of generator) {
console.log('In FOR loop; response; ', response);
}
谢谢,
克里斯托夫
您可以使用异步迭代器:
const arr = [{
"content": "FIRST_CONTENT_HERE",
"callback": function callback (_) { return _; }
},
{
"content": "SECOND_CONTENT_HERE",
"callback": function callback (_) { return _; }
},
{
"content": "THIRD_CONTENT_HERE",
"callback": function callback (_) { return Promise.resolve(_); }
},
{
"content": "FOUR_CONTENT_HERE",
"callback": function callback (_) { return _; }
}
];
async function* asyncGenerator(tasks) {
for (const task of tasks) {
yield task.callback(task.content);
}
}
;(async function() {
for await (const txt of asyncGenerator(arr)) {
console.log('->', txt);
}
})();
我想创建一个生成器来遍历该数组但不返回(yield?)控制权返回下一次迭代,直到执行该回调函数为止。
问题是生成器和 Promise 有根本不同的假设。 Promise 本质上是“我会一直致力于此,直到我完成,并在完成后给你回电”,而生成器本质上是“让我知道你何时准备好下一个”。
如果您使用的是生成器,那么您必须在下次调用该函数时返回一个值……您等不及了。所以问题是,等到第一个电话完成后再开始第二个电话对您来说有多重要?
如果你可以同时处理所有的调用,那么你的生成器可以只返回 Promise,你的调用代码可以负责
await
ing它们。
但是,如果按顺序一次处理一个标注很重要,则不能使用生成器。但是,您可以使用回调。
这可能不是完全你所希望的,但如果你必须确保一次按顺序调用一个标注,那么这是一个简单的解决方案。
const arr = [{
"content": "FIRST_CONTENT_HERE",
"callback": function callback () {}
},
{
"content": "SECOND_CONTENT_HERE",
"callback": function callback () {}
},
{
"content": "THIRD_CONTENT_HERE",
"callback": function callback () {}
},
{
"content": "THIRD_CONTENT_HERE",
"callback": function callback () {}
}
];
async function processList(itemCallback) {
for (const item of arr) {
await item.callback();
itemCallback(item);
}
}
async function callingCode() {
await processList(item => {
// Do something with item...
});
}
如果生成器更多的是关于便利性和语法美感而不是性能或技术要求,那么您可以只返回 Promises 并让调用代码处理它们:
const arr = [{
"content": "FIRST_CONTENT_HERE",
"callback": async function callback () {}
},
{
"content": "SECOND_CONTENT_HERE",
"callback": async function callback () {}
},
{
"content": "THIRD_CONTENT_HERE",
"callback": async function callback () {}
},
{
"content": "THIRD_CONTENT_HERE",
"callback": async function callback () {}
}
];
async function* getList() {
for (const item of arr) {
yield item.callback().then(() => item);
}
}
async function callingCode() {
for await (const item of getList()) {
// Do something with item
}
}