0

私はqライブラリを短期間使用していましたが、ajax から取得したデータを順次処理することに成功しました。

データの順次処理とは、各 ajax 呼び出しの後、一連の.then( function(){} )を実行し、次の ajax 呼び出しに進むことを意味します ...

単一のデータ エントリ (ajax データ) の処理の一環として、ajax の結果を画面に出力する必要があります。ajax データから div にテキストを入力した後に解決する遅延オブジェクトがあります。(Q のprogressHandlerを使用して) div へのテキストの入力が完了したことを通知しています (テキストの 100% が div に入力されました)。

q's v. 0.9.6 では、すべてが期待どおりに機能します。しかし、何らかの理由で v. 0.9.7 では TypeError {} :s が発生します。明らかに、遅延オブジェクトは進行状況を伝達せず、何らかの理由で失敗します。changelog はあまり役に立ちませんでした: q changelog

2 つのバージョンのコードを用意し、できる限り単純化しました。これは動作するバージョン - 0.9.6と動作しないバージョン - 0.9.7です。両方の例のコードは同じですが、唯一の違いは q ライブラリのバージョンです。

CSS セクションにコードの説明があります。私はそこでできるだけ明確であることを願っています。

これがばかげた質問である場合は、事前にお詫び申し上げます。


JSFiddle リンクを投稿することはできないため、コードは次のとおりです。

私が使用するライブラリ:

  • jQuery
  • ajaxFake by ANas Nakawa
  • Teletype (私 - div にテキストを入力するため)
  • yodaProgress (私 - グラフィカルな進行状況バー。.progress(step 0.00 - 1.00) および .isDone() 関数があります)
  • q v. 0.9.6 / q v. 0.9.7

HTML :

<div id="progress_1"></div>

Javascript :

$(document).ready(function() {

    // For DEFERRED object (referencing in 2.2.1)
    var mainObject = {
    }

    // For fake ajax Data
    $.ajax.fake.registerWebservice('blah', function (data) {
        return {
            result: 'My fake ajax result should be typed into the div!', 
        };
    });

    // 1. START
    var nextTick = Q.when();

    // 2. PROCESS 3 ITEMS SEQUENTIALLY
    for (var i = 0, length = 3; i < length; i ++) {
        nextTick = nextTick.then(
            processAjaxCall,
            function(error)     { console.log("This is an error 2.");   },
            function(progress)  { console.log("This is a progress 2."); }
        );

    }

    // 3. FINALLY DO THIS
    nextTick.fin(
        function(result)    { console.log("This is a final result 3.");     },
        function(error)     { console.log("This is an error 3.");   },
        function(progress)  { console.log("This is a progress 3.");}
    );


    // 2.0   ONE OF 3 SEQUENTIALL ITEMS
    function processAjaxCall () {

        var fakeResult;

        // 2.1.   AN AJAX DATA
        var promise = Q.when(
            fakeAjax()
        );

        // 2.2.   SETTING OF TEXT (from 2.1.) INTO DIV
        var promiseToDo = promise.then(
            function (result) {
                console.log("Result of ajax call:", result);
                return setText(result);
            },
            function (error)    { console.log("Ajax call error 2.2:", error);       },
            function (progress) { console.log("Ajax call progress 2.2:", progress); }
        );

        // 2.3. SETTING OF PROGRESS (100% - color green for a DIV)
        return promiseToDo.then(
            function (result) {
                console.log("Text was set 2.3");
            }, 
            function (error) {
                console.log("Error 2.3:", error);
            }, 
            function (progress) {

                var promiseElement = new YodaProgress(

                    $("#progress_1")

                    ,{
                        doneCSSRule: {
                            'background-color': "#00CC00"
                        }
                    }
                );

                promiseElement.progress(parseFloat(progress).toFixed(2));

                if (promiseElement.isDone()) {
                    mainObject.deferred.resolve();
                }

                //console.log("2.3 Progress %:", progress);
            }
        );

    }


    // 2.1.1 - a fake Ajax Data
    // Anas Nakawa
    // https://github.com/anasnakawa/jquery.ajax.fake
    function fakeAjax () {
        return $.ajax({
            type:'GET',
            dataType:'jsonp',
            fake: true,
            url:'blah'
        });
    }

    // 2.2.1 - setting text into a DIV
    function setText (result) {

        console.log('Passing in result:', result);
        console.log('About to set text to:', result.result);

        mainObject.deferred = Q.defer();
        promise = mainObject.deferred.promise.when(

            // Teletype is a library to type text into a DOM element
            // as if human was typing, sorta
            Teletype(
                document.getElementById("progress_1"), 
                result.result, 
                40, 
                true, 
                function (i, l) {

                    mainObject.deferred.notify(
                        parseFloat((i+1)/l).toFixed(2)
                    );
                }
            )
            //,function(error)      { console.log("This is an error 2.2.1", error);       }
            //,function(progress)   { console.log("This is a progress 2.2.1", progress);}
        );
        console.log("RETURNING PROMISE");
        return promise;
    }


});

説明:

  If it is v. 0.9.7 I GET a "TypeError {}" and div is typed in differently
  If it is v. 0.9.6 it works as expected.

  Code Explanation:

  Forget the ugliness and everything.
  This code is modified for illustrative purposes.

  What this code does is basically this:

  - Process 3 sequential function calls

    - these calls turns out to consist of:

      - an ajax Call
      - setting div #progress_1 TEXT with ajaxCall response
      - on progress of setting text into a #progress_1 div make DIV green.
 */

PS ページを読み込んで後で Chrome でコンソールを開くと、調べることができる TypeError オブジェクトが表示され、「オブジェクトには 'when()' メソッドがありません」と表示されます。それは私にどこから始めるべきかの手がかりを与えました. その前に、ページをロードする前にコンソールが Chrome で開いていた場合、「TypeError {}」メッセージが表示されます。なぜこのように操作に大きな違いがあるのか​​ について、さらに調査する必要があります。

どうもありがとう!

4

1 に答える 1

0

わかりました、私は問題を解決しました:p

0.9.7 リリースで deferred オブジェクトの構造が内部的に変更されたようです。奇妙な変更ログファイルには、「0.9.6」セクションの変更に関する情報が表示されます。

0.9.6 でコンソールを確認すると、

var deferred = Q.defer();
deferred.promise.__proto__ 

when()機能があることがわかります。deferred.promise は実際の Promise オブジェクトではなく、何か違うものですか?.

ただし、バージョン 0.9.7 で同じことを確認すると、

var deferred = Q.defer();
deferred.promise.__proto__ 

メソッドを持つ Promise オブジェクトが返され、then()「when()」メソッドが存在しなくなりました。

そうそう、changelog は誤解を招くものだったか、気が狂ってしまったのかもしれません。

GitHub q ライブラリのリポジトリに移動し、"Tags" -> "0.9.6" -> "CHANGES.md" ファイルを選択すると、ファイルの最上部に "0.9.5" セクションが表示されます。したがって、著者は、これらが 0.9.6 にある 0.9.5 からの変更 あることを伝えようとしたと思います。

master ブランチリストは0.9.7の下で変更されるため、おそらくそれは理にかなっています。したがって、再び 0.9.7 から次のバージョンに変更さます (私は 0.9.8 と仮定します)。

これで、変更ログの数字を信用しないほうがよいことがわかりました! :p

参加してくれたみんなありがとう!

于 2013-09-17T02:35:52.683 に答える