1

最後にキャッチを配置していますが、少なくとも特定のインスタンスで空のオブジェクトを返しています。知らないことにはキャッチが必要ですか、それとも私を台無しにするだけですか?

$( document).ready(function(){
    app.callAPI()//a chainable a RSVP wrapper around a jquery call, with its own success() fail() passing forward to the wrapper, so it will either be a resolved or rejected thenable to which is now going to be chained 
        .then(
            function(env) {
                //set the property you needed now
                app.someSpecialEnvObj = env;
            },
            function(rejectMessage){
                console.log('call.API() cant set some special env object..');
                console.log(rejectMessage);
            }
        )
        .catch(
        function(rejectMessage){
            if(rejectMessage){
                //a just incase, DOES IT HAVE VALUE, for somebody that may have not done their homework in the parent calls?
                console.log('you have some kind of legitimate error, maybe even in callAPI() that is not part of any problems inside them.  you may have forgotton handle something at an early state, your so lucky this is here!)
            } else {
                console.log('can this, and or will this ever run.  i.e., is there any value to it, when the necessity to already be logging is being handled in each and every then already, guaranteeing that we WONT be missing ANYTHING')
            }
        }
    );
});

違いますか?.then(resolve, reject)または、すべての親チェーンされた then-ablesのメソッドのすべての使用法でエラー/拒否ハンドラーを使用している場合でも、何らかの用途がありますか?

編集:より良いコード例、私は願っています。私はまだ命名にある種のアンチパターンを使用している可能性があると思います.rejectMessage例えば、それはjqXhrオブジェクトですよね?

だから多分私はそれらに正確にその名前を付ける必要がありますか?つまりjqXhr?ちなみに、then()エラーがあった場合、 each 内のその場で拒否するのが好きな理由は、この方法で個々の呼び出しを大量にログに記録できるためです。特に問題があった場合、その方法ではありません何かを追跡するために。できるので、マイクロロギング。

Promise は、このようにデバッグの世界を開くのに役立っています。

これが私が試した3つの例です。私は方法 1 と方法 2 を好みますが、私が約束の地で出発した方法 3 に戻ることは決してありません。

//method 1
app.rsvpAjax = function (){
    var async,
        promise = new window.RSVP.Promise(function(resolve, reject){
            async = $.extend( true, {},app.ajax, {
                success: function(returnData) {
                    resolve(returnData);
                },
                error: function(jqXhr, textStatus, errorThrown){
                    console.log('async error');
                    console.log({jqXhr:  jqXhr, textStatus: textStatus, errorThrown: errorThrown});
                    reject({ jqXhr: jqXhr, textStatus: textStatus, errorThrown: errorThrown}); //source of promise catch data believe
                }
            });
            $.ajax(async); //make the call using jquery's ajax, passing it our reconstructed object, each and every time
        });
    return promise;
};

app.callAPI = function () {
    var promise =app.rsvpAjax();
    if ( !app.ajax.url ) {
        console.log("need ajax url");
        promise.reject(); //throw (reject now)
    }
    return promise;
};

//method 2
app.ajaxPromise = function(){
    var  promise,  url = app.ajax.url;
    var coreObj = { //our XMLHttpRequestwrapper object
        ajax : function (method, url, args) {  // Method that performs the ajax request
            promise = window.RSVP.Promise( function (resolve, reject) {    // Creating a promise
                var client = new XMLHttpRequest(),  // Instantiates the XMLHttpRequest
                    uri = url;
                uri = url;
                if (args && (method === 'POST' || method === 'PUT')) {
                    uri += '?';
                    var argcount = 0;
                    for (var key in args) {
                        if (args.hasOwnProperty(key)) {
                            if (argcount++) {
                                uri += '&';
                            }
                            uri += encodeURIComponent(key) + '=' + encodeURIComponent(args[key]);
                        }
                    }
                }
                client.open(method, uri);
                client.send();
                client.onload = function () {
                    if (this.status == 200) {
                        resolve(this.response);   // Performs the function "resolve" when this.status is equal to 200
                    }
                    else {
                        reject(this.statusText); // Performs the function "reject" when this.status is different than 200
                    }
                };

                client.onerror = function () {
                    reject(this.statusText);
                };
            });
            return promise;   // Return the promise
        }
    };
    // Adapter pattern
    return {
        'get' : function(args) {
            return coreObj.ajax('GET', url, args);
        },
        'post' : function(args) {
            return coreObj.ajax('POST', url, args);
        },
        'put' : function(args) {
            return coreObj.ajax('PUT', url, args);
        },
        'delete' : function(args) {
            return coreObj.ajax('DELETE', url, args);
        }
    };
};

app.callAPI = function () {
    var async, callback;
    async =app.ajaxPromise() ; //app.ajaxPromise() is what creates the RSVP PROMISE HERE<
    if(app.ajax.type === 'GET'){async = async.get();}
    else if(app.ajax.type === 'POST') {async = async.post();}
    else if(app.ajax.type === 'PUT'){async = async.put();}
    else if(app.ajax.type === 'DELETE'){ async = async.delete();}
    callback = {
        success: function (data) {
            return JSON.parse(data);
        },
        error: function (reason) {
            console.log('something went wrong here');
            console.log(reason);
        }
    };
    async = async.then(callback.success)
        .catch(callback.error);
    return async;
};

//method 3 using old school jquery deferreds
app.callAPI = function () {
    //use $.Deferred instead of RSVP
    async = $.ajax( app.ajax) //run the ajax call now
        .then(
        function (asyncData) { //call has been completed, do something now
            return asyncData;  //modify data if needed, then return, sweet success
        },
        function(rejectMessage) {  //call failed miserably, log this thing
            console.log('Unexpected error inside the callApi.  There was a fail in the $.Deferred ajax call');
            return rejectMessage;
        }
    );
    return async;
};

onreadyまた、これを別のバックアップとしてどこかで実行します。

window.RSVP.on('error', function(error) {
    window.console.assert(false, error);
    var response;
    if(error.jqXhr){
        response = error.jqXhr;
    } else {
        //response = error;
        response = 'is this working yet?';
    }
    console.log('rsvp_on_error_report')
    console.log(response);
});

エラー例の編集

//one weird error I can't understand, an empty string("")?
{
  "jqXhr": {
    "responseText": {
      "readyState": 0,
      "responseText": "",
      "status": 0,
      "statusText": "error"
    },
    "statusText": "error",
    "status": 0
  },
  "textStatus": "error",
  "errorThrown": "\"\""
}
//another wierd one, but this one comes from a different stream,  the RSVP.on('error') function
{
  "readyState": 0,
  "responseText": "",
  "status": 0,
  "statusText": "error"
}
4

3 に答える 3

3

最後にキャッチを入れています

それが彼らの典型的な立場です - チェーンのどこかで発生していたすべてのエラーを処理します。エラーを処理することをまったく忘れないことが重要であり、最後にキャッチオールを持つことをお勧めします。

すべての呼び出しonrejectでハンドラーを使用しても?.then(…)

それは少し奇妙です。通常、すべてのエラーは中央の場所 (catch最後) で処理されますが、もちろん、必要に応じてどこでもエラーを処理して、チェーンを続行できます。

のハンドラとのハンドラの違いonrejectthencatchを理解しておくだけで、自由に使用できます。それでも、最終的には、コールバック自体catchでエラーをキャッチすることをお勧めします。then

少なくとも1つの特定のインスタンスで空のオブジェクトを返しています。

その後、約束は台無しになりました-理由なしに拒否することは決してありません. が原因のようです

if ( !app.ajax.url ) {
    console.log("need ajax url");
    promise.reject();
}

だったはずのコードで

if (!app.ajax.url)
    return Promise.reject("need ajax url");

知らないことにはキャッチが必要ですか?

あまり。問題は、catch通常はキャッチオールであり、予期しない例外をキャッチすることです。では、それらを区別できるとしたら、予期しないものをどうしますか?

通常、それらに対してある種のグローバルな未処理の拒否ハンドラーを設定し、すべてのプロミス チェーンの最後でそれらを手動で処理する必要がないようにします。

于 2015-06-17T05:08:01.240 に答える
1

私の記憶が正しければ、プロミスが拒否されると catch が起動します。失敗コールバックがアタッチされているため、失敗コールバックまたは成功コールバックで reject 関数を呼び出さない限り、catch は起動しません。つまり、catch ブロックは then メソッドで拒否をキャッチしています。

于 2015-06-17T04:34:03.893 に答える