検索

ホームページ  >  に質問  >  本文

angular.js - angularjs $q の Promise はネストされた Ajax 問題をどのように解決しますか?

質問 1: 最初の ajax リクエストによって返されたデータを 2 番目の ajax のパラメーターとして使用する必要があり、2 番目の ajax は最初の ajax のコールバック関数で送信されます。しかし、問題があります!ただ、2回目にajaxから返されたデータをグローバルオブジェクトのプロパティに割り当てることができないということは、私が落とし穴に落ちたかどうかはわかりません。そこで $q を使って解決したいと思います。
質問 2: この例を見てみましょう。
// $q は組み込みサービスなので、直接使用できます。
ngApp.factory('UserInfo', ['$http', '$ q', function ($http, $q) {
return {

リーリー

};
}]);
deferred.resolve は実行を遅らせるためですか?では、コールバック関数にロジックを記述できるのであれば、なぜわざわざ実行を遅らせる必要があるのでしょうか?
質問 3: deferred.promise によって返される Promise が最終的なデータ API であると言われるのはなぜですか?この約束にはどのような役割があるのでしょうか?
質問 4: Promise.then の実行ロジックは何ですか?

阿神阿神2872日前542

全員に返信(1)返信します

  • PHPz

    PHPz2017-05-15 17:05:42

    すべての質問に答える前に、まずサンプル コードについて簡単に説明させてください。 !

    あなたのサンプルコードは、Promise の典型的な否定的な教材です。その特徴は、目的もなく deferred オブジェクトを作成することであり、コードの複雑さが増すだけです。これについては、アンチパターンをここで確認できます: Promise的反面教材,其特征就是:无目的的创建deferred对象,徒增代码复杂度。关于这点,可以看这里anti-pattern:

    纠正问题之后,我们再来回头谈你的问题。

    首先,当你意识到自己正在忍受callback hell的时候,恭喜你,在javascript这条路上,你算上道儿了。那么解决之道有哪些呢?我们最近常见的有:

    • Promise

    • generator配合co

    • async/await

    关于这几种方式的详细介绍,我没仔细翻别人的答案(或许有更好的),只能把自己之前写的贴出来javascript里的异步

    OK,介绍了解决callback hell的几种常见方式,再回头来说你的Promise问题

    问题一:我需要用第一次发送ajax请求回的数据作为第二次ajax的参数,而第二次的ajax是在第一次ajax的回调函数里发送的。但是这里有问题!就是第二次ajax返回的数据不能赋值给全局对象的属性,不知道是不是掉到坑里了。所以想用$q解决。

    既然我们寄希望于Promise能够解决回调地狱的问题,拿肯定不会再是使用回调的方式,你的疑惑是对的,可你的问题是没有充分理解Promise是这么工作的。我先举个例子:

    var call1 = function(cb) {
        setTimeout(function() {
            cb('call1');
        }, 10);
    };
    
    var call2 = function(param1, cb) {
        setTimeout(function() {
            cb(param1 + ' + call2');
        }, 10);
    };
    
    call1(function(param1) {
        call2(param1, function(param2) {
            console.log(param2); //call1 + call2
        });
    });

    这是一个典型的回调依赖,call2依赖了call1的结果。如果用Promise改写,应该是什么样子呢?

    var call1 = function() {
        return new Promise(function(resolve, reject) {
            setTimeout(function() {
                resolve('call1');
            }, 10);
        });
    };
    
    var call2 = function(param1) {
        return new Promise(function(resolve, reject) {
            setTimeout(function() {
                resolve(param1 + ' + call2');
            }, 10);
        });
    };
    
    call1()
        .then(function(param1) {
            return call2(param1);
        })
        .then(function(param2) {
            console.log(param2); //call1 + call2
        });

    这里有几个要注意的地方,1. 无需不必要的deferred对象,call1call2本身返回Promise对象即可; 2. resolve几乎扮演了之前cb的角色; 3. 当执行call1call2时,不塞入回调,而是通过then拿到返回结果 4. 尤其return call2(param1);这个地方,真的不要再度嵌套(很多初入Promise的选手犯的错),直接返回,下一个then里就能拿到结果

    问题二:那这个例子来说吧

    这就是最早说的问题,你过度反应了,明显把简单问题复杂化了,这么写足矣:

    ngApp.factory('UserInfo', ['$http', '$q', function($http, $q) {
        return {
            query: function() {
                return $http({method: 'GET', url: 'scripts/mine.json'});
            }
        };
    }]);

    调用的地方,直接用then

    #🎜🎜#
    #🎜🎜#問題を修正した後、もう一度問題について話し合うことにします。 #🎜🎜#
    #🎜🎜#まず第一に、コールバック地獄に耐えていることに気づいたとき、おめでとうございます。あなたはjavascriptへの道を進んでいます。では、解決策は何でしょうか?最近見たものは次のとおりです: #🎜🎜#
    • #🎜🎜#約束#🎜🎜#
    • #🎜🎜#generator は co#🎜🎜# と協力します
    • #🎜🎜#非同期/待機#🎜🎜#
    #🎜🎜# これらのメソッドの詳細な紹介については、他の人の回答をよく読んでいないので(もっと良い回答があるかもしれません)、以前に書いたものしか投稿できません#🎜🎜# #🎜🎜#OK、コールバック地獄を解決する一般的な方法をいくつか紹介しました。その後、Promise の問題に戻ります#🎜🎜# #🎜🎜#質問 1: 最初の ajax リクエストによって返されたデータを 2 番目の ajax のパラメーターとして使用する必要があり、2 番目の ajax は最初の ajax のコールバック関数で送信されます。しかし、問題があります!ただ、2回目にajaxから返されたデータをグローバルオブジェクトのプロパティに割り当てることができないということは、私が落とし穴に落ちたかどうかはわかりません。そこで $q を使って解決したいと思います。 #🎜🎜# #🎜🎜#Promise がコールバック地獄の問題を解決できることを願っているため、今後はコールバックを使用しないことは間違いありません。しかし、あなたの質問はこのように完全には理解されていません。 >Promise は機能します。まずは例を挙げましょう: #🎜🎜# リーリー
    #🎜🎜#これは典型的なコールバック依存関係であり、call2call1 の結果に依存します。 Promise を使用して書き換えると、どうなるでしょうか? #🎜🎜#
    リーリー
    #🎜🎜#ここで注意すべき点がいくつかあります。 1. 不要な deferred オブジェクト、call1 および call2 自体は必要ありません。 Promise オブジェクトを返すだけです。 2. resolve は、前の cb の役割をほぼ果たします。 3. call1 を実行するとき。 > 、 call2 の場合、コールバックは挿入されませんが、戻り結果は then を通じて取得されます。 4. 特に return call2(param1);、本当に二度とネストしないでください (Promise を初めて使用する多くのプレイヤーが犯す間違いです)、直接戻って、次の then で結果を取得できます#🎜🎜 # #🎜🎜#質問 2: この例を見てみましょう#🎜🎜# #🎜🎜#これは最初の質問です。あなたは過剰反応しており、明らかに単純な問題を複雑にしています。#🎜🎜# リーリー #🎜🎜# どこに呼び出すかは、then を使用するだけです: #🎜🎜#リーリー

    3 番目と 4 番目の質問はすべて、Promise本身的实现没概念,我之前写过一个小教程,教大家自己手写一个Promise的简单实现,建议你跟着做做,先对Promise 自体についての一般的な理解と、段階的に約束を手書きする方法に基づいています

    返事
    0
  • キャンセル返事