2017-03-14 9 views
0

私はcontentRecordHelperというライブラリを使用するプロジェクトに取り組んでいます。 contentRecordHelper.addTitleFilter()を使用してレコードオブジェクトを実行すると、そのレコードの種類に基づいてさまざまなプロパティの集合がレコードに設定されます。前条件が真実であることを単に待つ約束を書くことができますか?

レコード:

{ 
    "_title": "Test Record", 
    "_type": "content", 
    "_id": "029828ABF" 
} 

それはcontentRecordHelper.addTitleFilter(通過しています後にレコード):

{ 
    "_title": "Test Record", 
    "_type": "content", 
    "_id": "029828ABF", 
    "server_id": "VAL8378", 
    "client_id": "SIRIUS", 
    "$titleFilter":"General", 
    "$contentFilter": "Standard:ContentRecord", 
    "$contentType":"", 
    "$systemType":"" 
} 

あなたは上から見ることができるように、空になって最後に追加した2つの属性があります:$ contentTypeと$ systemType。これらの2つは、contentRecordHelper.addTitleFilter()内で開始され、約1000ms後に追加される非同期関数によって生成されるためです。

ただし、このデータが生成されるとすぐに、グリッドに渡されます。情報が更新されていれば、そのグリッドを更新して、正しく表示できるようにする必要があります。幸い、そうするためにgrid.refreshGrid()関数があります。私のコードは次のようになりますので、私は、タイムアウトでそれを呼び出すされています:

function addRecordToGrid(record: any): void { 
    this.contentRecordHelper.addTitleFilter(record); 
    this.grid.rowData.push(record); 
    setTimeout(() => { 
     this.grid.refreshGrid(); 
    }, 1000); 
} 

今、厳密にこれが正常に動作しますが、私のシニア開発者の一つは、我々はハード千ミリ秒に頼るべきではないことを私に指摘話しますこれは遅いバックエンド接続の場合には常に信頼できるとは限らないためです。彼は代わりに、私は約束を使用する必要がありますので、すぐに記録する必要があります。$ systemType & &レコード。$ contentTypeが存在するので、grid.refreshGrid()を呼び出します。そして、彼は正しい - それは完璧な意味がある。唯一の問題は、私が前に約束を書いたことは一度もありません。私が見つけることができるすべての例は、非同期関数を呼び出して、完了するのを待ちます。私の場合、contentRecordHelper.addTitleFilter()は、結果の特定の部分が後で到達しなくてもほぼ即座に完了します。

私は、ちょうどちょうどと同じように、(レコード。$ systemType & &レコード。$ contentType)のように条件が真であるのを待つという約束を書くことができますか?それが不可能な場合、私の問題を解決する約束を使用するための最良の方法は何ですか? contentRecordHelper.addTitleFilter()を変更せずにこれを行うことは可能ですか?その機能の背後にあるメカニズムは非常に複雑で、もし私がそれに変更を加えることを避けることができれば、私に多くのストレスを与えません。

私が作業しているプロジェクト(および一般的にはタイスクリプト)にはかなり新しいので、これが明らかであれば謝ります。

+2

'contentRecordHelper.addTitleFilter'はコールバック引数を取っていない、または約束を返していませんか?ほとんどの非同期関数はそうしていますが、そうでない場合はそうする必要があります。 –

答えて

3

非同期コードがcontentRecordHelper.addTitleFilterであるため、非同期操作がいつ終了するのかわからないため、約束を返すのにはほとんど役に立ちません。
JavaScriptはイベント駆動型です。オブジェクトを待つ方法はありません。操作が完了したことを知る唯一の方法は、約束を返すcontentRecordHelper.addTitleFilterにコードを追加することです。あなたは何ができるか

はこれです:その後、

function addRecordToGrid(record: any): Promise<void> { 
    this.contentRecordHelper.addTitleFilter(record); 

    return new Promise<void>((resolve, reject) => { 
     const check =() => { 
      setTimeout(() => { 
       if (record.$systemType && record.$contentType) { 
        resolve(); 
       } else { 
        check(); 
       } 
      }, 1000); 
     } 

     check(); 
    }); 
} 

そしてそうのようにそれを使用します。

this.addRecordToGrid(record).then(() => this.grid.rowData.push(record)); 

しかし、あなたが見ることができるようにプロパティが設定されるまで、それだけでタイムアウトをループし続けます実際に操作が終了したことは実際にはわかりません。

+0

私はこの答えを正しいものか@Bergiの答えとして与えるかの間に裂けた。私は私の質問で言及したように、私は本当にcontentRecordHelper.addTitleFilter()に変更を加えることができないので、私は最終的にこれを選択しました。私は権利を持っていないし、ちょうど小さな変更を行う権利を得ることのフープを飛び越してカードにないです。あなたが提案した解決策は素晴らしいです。ありがとうございました! – SemperCallide

0

contentRecordHelper.addTitleFilter関数は非同期であるため、終了時に何らかの方法で通知する必要があります。プロミス(正しい方法)を返すか、コールバック(古い方法)を取るか、タイトルフィルタが追加されるとイベントが発生します。

を変更できない場合は、Nitzamの回答のように、ポーリングなどのハッキングに頼らざるを得ません。

3

ちょうどちょうどちょうど、条件が真であるのを待つ、約束を書くことができますか?例えば、(record.$systemType && record.$contentType)

はい、それはtrivially possibleです。しかし、いいえ、これはあなたがすべきことではありません。あなたは普通のsetTimeoutでポーリングを行ってもいいかもしれません(データが利用できない限りrefreshGrid呼び出しを繰り延べるだけです)が、このは上級者がを意味するものではありません。

彼は代わりに、私は約束

を使用するべきであると述べたとcontentRecordHelper.addTitleFilter()が、それは、レコードの更新を完了したときのための約束を返すべきであることを意味しました。あなたはその後、もちろん

function addRecordToGrid(record: any): void { 
    this.contentRecordHelper.addTitleFilter(record).then(() => { 
     this.grid.refreshGrid(); 
    }); 
    this.grid.rowData.push(record); 
} 

を書くでしょう、いや、それはaddTitleFilterを変更することなく、可能ではないですが、ときevery asynchronous function returns a promiseは、あなたが単に上に鎖またはreturnことができ、それは比較的簡単なはずです。

関連する問題