2017-06-13 4 views
0

私はopenShapeFileというファイルを読み込み、read関数を持つソースオブジェクトをラップするPromiseを生成し、これはShapefileの実際の値をラップするPromiseを返しますファイルの末尾に達したかどうかを判断するために使用できるブール値は.doneです。ここから大きなファイルの非同期反復のためのジェネレータ

効果で

shapefile.open:ちょうど作品について

openShapeFile(`shapefile.shp`).then((source) => source.read() 
    .then(function log(result) { 
    if (result.done) { 
     return 
    } else { 
     let query = `INSERT INTO geodata(geometry, id, featcode) VALUES(ST_GeomFromGeoJSON('${ 
     JSON.stringify(Object.assign({}, result.value.geometry, {coordinates: result.value.geometry.coordinates.map(JSON.stringify)})) 
     }'), '${ 
     result.value.properties.ID 
     }', ${ 
     result.value.properties.FEATCODE 
     });` 
     query = query.split('"[[').join('[[').split(']]"').join(']]') 
     return pool.query(query).then((result) => { 
     return source.read().then(log) 
     }) 
     } 
     })).then(() => console.log(dirCount)).catch(err => 'Problem here'))) 

これを、しかし、再帰があります ​​

私は今、データベースにファイルを読みたい場合は、私が言うことができますPromise(weird)

練習として、そして/またはそれがより明確になるかどうかを確認するために、私はそれを次のように生成することにしました。

function *insertQuery(query) { 
    const result = pool.query(query) 
    return result 
    } 

    const shapeFileGenerator = co.wrap(function* (source) { 
    while (true) { 
     const result = yield source.read() 
     if (result.done) { 
     return yield {} 
     } else { 
     let query = `INSERT INTO geodata(geometry, id, featcode) VALUES(ST_GeomFromGeoJSON('${ 
      JSON.stringify(Object.assign({}, result.value.geometry, {coordinates: result.value.geometry.coordinates.map(JSON.stringify)})) 
     }'), '${ 
      result.value.properties.ID 
     }', ${ 
      result.value.properties.FEATCODE 
     });` 
     query = query.split('"[[').join('[[').split(']]"').join(']]') 
     yield* insertQuery(query) 
     } 
    } 
    }) 
openShapeFile(`shapefile.shp`).then((source) => { 
    const s = shapeFileGenerator(source) 
}))) 

これが機能します。それはすべてのデータを読み込みます! しかし、私は無限ループを嫌い、.nextを直接呼び出すことはありません。どのように私はこれを再加工できますか?ジェネレータを使ってこのようなことを行う慣習的な方法は何でしょうか?私はs.next()と適切な発電機を書くことができるでしょうのように思われるsource.read()の結果ですか?

+0

約束のある発電機を使用しないでください! 'async' /' await'を使用してください! – Bergi

+0

"*私は決して.nextを直接呼び出すことはありません*" - 'co'ライブラリがそれを行います。なぜあなたはそれをしたいのですか? – Bergi

答えて

-1

ロジックが同期しているかのようにコーディングし、シーケンシャルエグゼキュータnsynjsで実行できます。以下は、わずかに変更された実施例はthis file上でテストされています。

main.js:いくつかの関数呼び出しが戻ると約束する場合

Nsynjsが自動的に検出されますが。はいの場合、それは解決する約束を待って、その結果をdataプロパティに入れ、次の式だけ続ける。

0

私はどちらかの再帰的な解決策に何か問題がないと思う

async function readFileToDB(filename) { 
    const source = await openShapeFile(filename); 
    for (let {value, done} = await source.read(); !done; {value, done} = await source.read()) { 
     const query = `INSERT INTO geodata(geometry, id, featcode) VALUES(ST_GeomFromGeoJSON('${ 
      JSON.stringify(value.geometry) 
     }'), '${ 
      value.properties.ID 
     }', ${ 
      value.properties.FEATCODE 
     });` 
     const result = await pool.query(query); 
    } 
    console.log(dirCount); 
} 
readFileToDB(`shapefile.shp`).catch(err => console.error('Problem here', err)); 

厳しい書くでしょう。

私は適切な発電機をs.next()と書いて、source.read()になるはずですか?

いいえ、ジェネレータは同期していません。あなたはasync iteration proposalを見てみたいかもしれません。

関連する問題