2016-05-18 8 views
2

複数のユーザーのデータを読み込み、javascript配列に格納します。 純粋typescriptですで、私はそのように書きます:Typescriptのlambdasとclosure(スコープ)

for(var i = 0; i < 5; i++) { 
    promise[i] = httpquery.then( 
    (data) => { this.usersData[i] = data } 
    ); 
) 

... 

this.$q.all[promise].then(...... 

残念ながら、私のtypescriptですラムダはこれだけ(とない変数i)を保護します。したがって、私の場合、常にthis.usersData [5]にデータが格納されます。

私はクロージャーが必要です。ラムダ式は、このタイスクリプトの言語の一部を理解する限り、クロージャーに少し似ています。

ので、活字体で何かをしてみましょう:

for(var i = 0; i < 5; i++) { 
    promise[i] = (index = i) => { 
     return httpquery.then( 
      (data) => { this.usersData[index] = data } 
     ); 
    }(); 
) 

(コンパイルさえない)全く動作しませいます。どうして ?なぜなら、()=> {}は実際には関数ではないようだからです。私はこの方法でこれを解決しました:

for(var i = 0; i < 5; i++) { 
    var getData = (index = i) => { 
     return httpquery.then( 
      (data) => { this.usersData[index] = data } 
     ); 
    }; 
    promise[i] = getData(); 
) 

私は非常に美しく見えません: - p。 私の質問は次のとおりです。この問題をどのように進めるか?私のように?または、より美しい方法でタイスクリプトでラムダを使用する方法がありますか? そして、なぜ

() => {}() 

が動作していないが、

var test =() => {}; 
test(); 

作品?これはラムダが関数であることを理解するのに十分な "スマート"ではないタイプスクリプトコンパイラのためですか?

ありがとうございました。

答えて

2

理由:。それにはJavaScript(var x = a => { return a + 1; }(3)はJavaScriptでSyntaxErrorだけでなく、活字体では有効ではありませんので、

promise[i] = (index = i) => { 
    return httpquery.then( 
    (data) => { this.usersData[index] = data } 
); 
}(); 

解析はしないだけで、括弧内のラムダをラップするには十分です

しかし、これを行うだけでは、キャプチャの問題は解決されません。デフォルトの引数は各呼び出しで評価されるため、すべてvarの最終バインド値を指します。

代わりにすることができますいずれか:活字体は自動的に正しいことを行います。その場合には、あなたの初期化子でletを使用する

A)スイッチ(:

for(let i = 0; i < 5; i++) { 
    promise[i] = httpquery.then(data => this.usersData[i] = data); 
} 

B)を手動で閉鎖を自分で作成します。

for(var i = 0; i < 5; i++) { 
    promise[i] = (index => httpquery.then(data => this.usersData[index] = data))(i); 
} 
+0

実際、letを使用するのが最も美しい解決策です。私はまだvarを使い、let/constを見る時間がかからなかったので、この悪い習慣を変えるための正しい時だと思います。 ありがとう! – Adavo

関連する問題