2017-06-15 1 views
0

Elasticsearchに対して「スクロール」要求を行うことは可能です。それはカーソルを開いたままにしておき、大量のデータを一片ずつ取り出すことができます。再帰でジェネレータを作成し、約束がうまく再生する

There's some demo code availableコールバックと再帰を使用してデータが取得されるまでデータを取得します。私が書いているNodeアプリケーションでは、データのすべてのチャンクをzipにストリームしたり、どこかに書き込んだりして、それを忘れて新しいデータを取得したいと思っています。しかし、この例では、すべてのデータを配列に格納するため、大量のデータに対してメモリの問題が発生する可能性があります。

ジェネレータ関数は、その後、すべての.next()にElasticsearchからいくつかのデータをフェッチスクロールエンドポイントと使用再帰からいくつかのデータを取得する別の.next()を呼び出す前に、それを離れて書くことが完璧になります。

私は現在、これがどのように達成されるのか本当に混乱しています。私たちは同期するために、(Elasticsearch呼び出し)の約束を待ってから解決しなければなりません。しかし、それはまた、再帰関数などを生成する必要があります。

異なる方法で何時間も試した後、ジェネレータの関数、約束、および再帰の組み合わせが私を混乱させました。うまくいけば、誰かがこのような何かを達成することができる方法を指摘することができ

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();

:私は私が達成しようとしている何に似ているいくつかの単純化されたコードを書きました。ありがとう!

答えて

2

いいえ、これは達成できません。発電機とfor … ofは同期しています。もちろん、あなたは約束をすることができますが、それはあなたに何も買わないので、代わりにasync/awaitの構文を使うのが良いでしょう。

しかし、あなたはasync iteration proposalを見てみたいです。

関連する問題