2017-01-31 5 views
0

配列を反復処理し、各項目に連鎖する約束を送る方法がわかりません。私はDBSchema.executeMigrationsを下に定義しようとしています(そこのコメントの詳細)。typescriptで引数の静的な配列から約束を結ぶ方法

migrationsが時間とともに成長すると仮定します。だから、今は3つの議論だが、来年は100になるだろう。私はこれを繰り返す必要がある。

export class DBConnection { 
    exec(query): Promise<any> { 
    let _this = this; 
    return new Promise((resolve) => { 
     _this.get().then((db) => { 
     db.executeSql(query, {}).then(
      (result) => { 
      resolve(result); 
      }, 
      (err) => { 
      console.log('Unable to execute query: ' + err.message); 
      } 
     ); 
     }); 
    }); 
    } 
} 


export class DBSchema { 

    constructor(public db_connection: DBConnection){}; 

    static migrations = [ 
    "CREATE TABLE IF NOT EXISTS events(id INTEGER PRIMARY KEY NOT NULL, title STRING)", 
    "CREATE TABLE IF NOT EXISTS news(id INTEGER PRIMARY KEY NOT NULL, title STRING)", 
    "CREATE TABLE IF NOT EXISTS whatever(id INTEGER PRIMARY KEY NOT NULL, title STRING)" 
    ]; 

    executeMigrations(): any { 
    // send each migration to db_connection.exec 
    // do it in order 
    // return a promise that resolves when all of them are done 
    } 
} 

答えて

1

約束は順番に実行し、解決しましょうへの道に簡単にはArray.prototype.reduce()でそれらを反復することです。そうすれば、即座に解決された約束で反復を開始し、約束の実行順序を配列から来る次の値と連鎖させることができます。

あなたのexec()機能は、悪い習慣とみなされるいわゆるdeferred anti-pattern/explicit promise construction patternで実装されているので、避けてください。あなたは代わりに_this.get()から返すべきである間に新しい約束を作る必要はありません。

既存の約束ではなく、それはこの

exec(query): Promise<any> { 
    let _this = this; 
    return _this.get().then((db) => { 
     return db.executeSql(query, {}) 
      .then((res) => { return res }) //not really necessary but to make it more clear 
      .catch((err) => { 
       console.log('Unable to execute query: ' + err.message); 
      } 
     ); 
     }); 
    } 

ように見えるようになり、Array.prototype.reduce()を使用することにより、すべてのクエリが順番に実行させることができ、これ

のような機能でお互いを待つ返すようにあなたの関数をリファクタリング
executeMigrations(): Promise<any> { 
     return DBSchema.migrations.reduce((previousValue: Promise<string>, currentValue: string): Promise<any> => { 
      return previousValue.then(() => { 
       return this.db_connection.exec(currentValue); 
      }); 
     }, Promise.resolve()); 
    } 

約束はちょうど、あなたが定期的に.then()と他のものを継続することが容易になり、すべての「内側」の約束が解決されたときに解決されexecuteMigrations()から返さexecuteMigrations().then(...)のように。

+0

すばらしい素晴らしい応答のおかげで、お元気です... exec()の 'then'行のどの部分が不要ですか? – jsharpe

+0

あなたは大歓迎です!それについて考えると、 'res'という値は' db.executeSql() 'から返され/解決されるので、結果を単に返すために余分な' .then() 'を追加する必要はありません。実際に結果が返されたことを示すためにコードに含めました。それを実証する[this jsfiddle](https://jsfiddle.net/0sL1ffa4/)を見てください! –

関連する問題