web-dev-qa-db-ja.com

AngularJSを使用して、解決されたプロミスをすぐに返す

JavaScript(特にAngularJS)での約束を回避しようとしています。

サービスに関数があります。それをfooServiceと呼び、データをロードしたかどうかを確認します。持っている場合は返すだけで、持っていない場合は、データをロードしてプロミスを返す必要があります。

_this.update = function(data_loaded) {
    if (data_loaded) return;  // We've loaded the data, no need to update

    var promise = Restangular.all('someBase').customGet('foo/bar').then(function(data) {
        // Do something with the data here
    }

    return promise;
}
_

次のようなupdatefooService関数を呼び出す別の関数があります。

_fooService.update(data_loaded).then(function() {
    // Do something here when update is finished
})
_

ここでの私の問題は、update関数にデータをロードする必要がない場合、promiseが返されないため、.then()が他の関数で呼び出されないことです。ここでのアプローチはどうあるべきか-基本的に、Restangular呼び出しからデータを取得する必要がない場合は、update()関数からすぐに解決済みのプロミスを返したいですか?

25
samturner

現在受け入れられている答えは非常に複雑で、 deferred anti pattern を悪用しています。より簡単なアプローチを次に示します。

this.update = function(data_loaded) {
    if (data_loaded) return $q.when(data);  // We've loaded the data, no need to update

    return Restangular.all('someBase').customGet('foo/bar')
                             .then(function(data) {
        // Do something with the data here 
    });
};

または、さらに:

this._updatep = null;
this.update = function(data_loaded) { // cached
    this._updatep = this._updatep || Restangular.all('someBase') // process in
                                                .customGet('foo/bar'); //.then(..
    return this._updatep;
};
27

PromiseはJavaScriptネイティブと同じ構文を使用するため、既に解決済みのJavaScript promiseを使用して返すことができます。 Promise.resolve()

return(Promise.resolve("MyReturnValue"));
43
Elo

AngularJSの $ q サービスが役立ちます。 Kris KowalのQ promiseライブラリによく似ています。

Promiseまたはvalueを返す非同期メソッドがある場合は、 $ q.when メソッド。渡された約束、約束であれ値であれ、渡された約束に基づいて解決/拒否される、または値が渡された場合に解決される約束を作成します。

$q.when( fooService.update(data_loaded) ).then(function(data){
   //data will either be the data returned or the data
   //passed through from the promise
})

そして、更新関数で単に返すのではなくデータを返します

if (data_loaded) return data_loaded;
6
Patrick Evans

Elo's answer と同様に、async/await構文を使用して既に解決済みのプロミスを返すことができます。

this.update = async (data_loaded) => {

    if (data_loaded) 
        return await null;  // Instead of null, you could also return something else
                            // like a string "Resolved" or an object { status: 200 }
    else 
        return await OtherPromise();
}
0
Zanon