2017-12-21 3 views
3

これがなぜ機能しないのか分かりません。 LOADでネストされた非同期/待機ノードノード

module.exports = async function() { 
    try { 
     await load(); 

    } catch (ex) { 
     console.log(ex); 
     logger.error(ex); 
    } 
}; 

async function load() { 
    return await new Promise((resolve, reject) => { 
     TableImport.findAll().then((tables) => { 
      for (let table of tables) { 
       await loadData(table.fileName, table.tableName); 
      } 
      resolve(); 
     }).catch(function (err) { 
      reject(err); 
     }) 
    }) 
}; 


async function loadData(location, tableName) { 
    return await new Promise(function (resolve, reject) { 
     var currentFile = path.resolve(__dirname + '/../fdb/' + location); 

     sequelize.query("LOAD DATA LOCAL INFILE '" + currentFile.replace('/', '//').replace(/\\/g, '\\\\') + "' INTO TABLE " + tableName + " FIELDS TERMINATED BY '|'").then(function() { 
      resolve(tableName); 
     }).catch(function (ex) { 
      reject(); 
     }); 
    }); 
}; 

AWAITは述べ失敗:私は子供のロード処理にAWAITを行い、親機能を持っている...順番にLOADプロセスは、別のはとても基本的に、このように...と呼ばれるloaddataのを待って呼び出します。

await loadData(table.fileName、table.tableName); SyntaxError:予期しない識別子

明らかに、非同期の範囲について何か分かりません!

+0

「return await ...」を行う理由はありません。ただ約束を返す。また、既存の約束を巡って新たな約束を守るという約束のアンチパターンを避けるべきである。 – jfriend00

答えて

3

awaitは、非同期機能内でのみ使用できます。あなたは非同期関数の内部にネスト非非同期機能を持っている場合は、その機能にawaitを使用することはできません。

async function load() { 
    return await new Promise((resolve, reject) => { 
     TableImport.findAll().then((tables) => { 
      for (let table of tables) { 
       await loadData(table.fileName, table.tableName); 

あなたは上記.thenメソッドへのコールバックを持っています。このコールバックは非同期ではありません。これを修正するには、async tables => {を実行します。

loadは非同期とfindAllリターン約束ですので、あなたが.thenを使用する必要はありません。

async function load() { 
    const tables = await TableImport.findAll(); 
    for (let table of tables) { 
     await loadData(table.fileName, table.tableName); 
    } 
} 

私はloadDataが何をするか正確にはわからないと、あなたが順番にテーブルをロードする必要がある場合しかし、あなたはまた、これを並列化することができます

const tables = await TableImport.findAll(); 
const loadPromises = tables.map(table => loadData(table.fileName, table.tableName)); 
await Promise.all(loadPromises); 
  • return awaitあなたは既にRETであるため、不必要です約束を返す。ちょうどreturnが動作します。
  • 私が提案したように書き直すと、あなたが返すことを約束しているメソッドは、とにかく約束しているので、Promiseオブジェクトを使う必要はありません。
  • 元の関数は何も解決していなかったので、この関数は何も返さずに同じように動作します。
  • 元の関数もreject(err)でエラーを伝播していました。この関数は内部的にエラーを処理しないので、同様にエラーを伝播します。

あなたloadData機能もかなりの書き換えを簡素化することができる:あなたがawaitを使用していないので、

function loadData(location, tableName) { 
    const currentFile = path.resolve(__dirname + '/../fdb/' + location); 
    return sequelize.query("LOAD DATA LOCAL INFILE '" + currentFile.replace('/', '//').replace(/\\/g, '\\\\') + "' INTO TABLE " + tableName + " FIELDS TERMINATED BY '|'"); 
}; 
  • loadDataは非同期である必要はありません。あなたはまだ約束を返しています。
  • 元のコードでエラーが返されなかったので、.catchを追加するとよいでしょう。上のコードは.queryのエラーを返します。
  • あなたはテーブル名を渡しています。実際には戻り値で何もしないので、.thenを完全に削除しました。
+0

OK右...これらすべての変更を行いました...私はあなたのコメントのすべてを理解していますが、1つの質問です。以下では動作しません: '非同期機能の負荷を(){ リターンは新しい約束は(()拒否、解決=> { のconstテーブル=がTableImport.findAll()を待つ待つ;' 私は '新しい約束を削除するとき'それは働いています...理由を説明できますか? – user3597741

+0

この文でも、私はちょっと投げました:'非同期関数が非同期関数の内部にネストされている場合、その関数ではawaitを使用できません。私はLOADDATA非非同期を作ったと私は待っているとそれを呼び出すことができます - それは動作します.... – user3597741

+0

私はあなたが 'function loadData {return aPromise;} ... async function load(){await loadData();}' 'async' /' await'の使用はスコープと関係があります。 'loadData'は 'load'関数スコープにありません。そのスコープ内で呼び出されているだけです。 –

関連する問題