可以向 Elasticsearch 发出“滚动”请求。它使游标保持打开状态,您可以逐段检索大块数据。
There's some demo code available ,它使用回调和递归来不断获取数据,直到完成。在我正在编写的 Node 应用程序中,我希望将每个数据 block 流式传输到 zip 中或将其写入某处,然后忘记它并获取新的数据 block 。然而,在示例中,它们将所有数据存储到一个数组中,这可能会导致大量数据的内存问题。
生成器函数非常适合在每个 .next()
上从 Elasticsearch 获取一些数据,然后在调用另一个 .next()
之前将其写掉这将从滚动端点获取一些数据并使用递归。
我目前真的很困惑如何实现这一目标。我们必须同步等待 Promise(Elasticsearch 调用)解析,然后产生响应。但它还需要产生递归函数等。
在尝试了几个小时的不同方法之后,生成器函数、 promise 和递归的混合让我感到困惑。我编写了一些类似于我想要实现的简化代码:
console.clear();
// Elasticsearch search call
function searchMockPromise() {
return new Promise(resolve => {
setTimeout(() => {
let response = {};
response.hits = {
total: 50,
hits: [1, 2, 3, 4, 5]
};
resolve(response);
}, 2000);
});
}
// Elasticsearch scroll call
function scrollMockPromise() {
return new Promise(resolve => {
setTimeout(() => {
let response = {};
response.hits = {
total: 50,
hits: [1, 2, 3, 4, 5]
};
resolve(response);
}, 2000);
});
}
function* exportGenerator() {
let count = 0;
console.log("Executing search call first");
yield searchMockPromise()
.then(function* (resp) {
yield* scrollCallback(resp);
return resp.hits.hits;
});
function* scrollCallback(response) {
console.log("Executing scroll callback");
count += response.hits.hits.length;
if (response.hits.total !== count) {
console.log("Theres more data to fetch, now make a scroll call");
yield scrollMockPromise()
.then(function* (resp) {
console.log("It executed a scroll call");
yield* scrollCallback(resp);
return response.hits.hits;
});
}
}
}
function init() {
// We just want the generator to return the "response" objects from the callbacks of the Promises...
// E.g. every part of data we get from the generator, we can inject into a streaming zip or write it somewhere.
for (let data of exportGenerator()) {
const promise = yield data;
const output = yield promise;
console.log(output);
}
}
init();
希望有人能指出如何实现这样的事情。谢谢!
最佳答案
不,这无法实现。生成器和 for … of
是同步的。当然,您可以产生 promise ,但这不会给您带来任何好处 - 您最好使用 async
/await
语法。
但是,您需要查看 async iteration proposal .
关于javascript - 让带有递归和 Promise 的生成器运行良好,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44556974/