javascript - 让带有递归和 Promise 的生成器运行良好

标签 javascript node.js recursion ecmascript-6 generator

可以向 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/

相关文章:

javascript - Promise 和 async/await 组合,等待异步操作的理想方式?

ajax - 如何使用 mongoose.js 合并更新文档?

javascript - 请帮我一个递归函数

c++ - 从火柴棒制作数字的算法

java - Java中的链表递归

javascript - 有没有办法在 node.js 的对象字面量中指定 ES6 生成器方法?

javascript - 等待 Observable 完成以提交表单

javascript - app.post 不工作! "Cannot GET/up"

javascript - 如何使用 Jison 词法分析器返回多个标记

javascript - 理解餐 table 最佳座位算法的问题