プロモーションモード

3698 ワード

js非同期プログラミングスタイル
promiseモードはいつでも以下の3つの状態の一つにあります.未完成、既完成、拒否です.
promise.then(reolvedHandler,rejectedHandler)/完了と拒否の状態に対する処理は、自分のpromise組成カスケードthen()に戻ります.自分のpromiseがなければthen()は元のpromiseに戻ります.
promiseの状態は一回だけ変えられます. unful filled>rejectdは、状態が変わったら対応するコールバックを実行し、コールバックを追加した時に状態が変わったらすぐに実行します.
 
オリジナルのコールバック
function searchTwitter(term, onload, onerror) {

 

     var xhr, results, url;

     url = 'http://search.twitter.com/search.json?rpp=100&q=' + term;

     xhr = new XMLHttpRequest();

     xhr.open('GET', url, true);

 

     xhr.onload = function (e) {

         if (this.status === 200) {

             results = JSON.parse(this.responseText);

             onload(results);

         }

     };

 

     xhr.onerror = function (e) {

         onerror(e);

     };

 

     xhr.send();

 }

 

 function handleError(error) {

     /* handle the error */

 }

 

 function concatResults() {

     /* order tweets by date */

 }

 

 function loadTweets() {

     var container = document.getElementById('container');

 

     searchTwitter('#IE10', function (data1) {

         searchTwitter('#IE9', function (data2) {

             /* Reshuffle due to date */

             var totalResults = concatResults(data1.results, data2.results);

             totalResults.forEach(function (tweet) {

                 var el = document.createElement('li');

                 el.innerText = tweet.text;

                 container.appendChild(el);

             });

         }, handleError);

     }, handleError);

 }

プロモーション方式
var Promise = function () {

        /* initialize promise */

    };

Promise.prototype.then = function (onResolved, onRejected) {

     /* invoke handlers based upon state transition */

 };

Promise.prototype.resolve = function (value) {

     /* move from unfulfilled to resolved */

 };

 

 Promise.prototype.reject = function (error) {

     /* move from unfulfilled to rejected */

 };



function searchTwitter(term) {



    var url, xhr, results, promise;

    url = 'http://search.twitter.com/search.json?rpp=100&q=' + term;

    promise = new Promise();

    xhr = new XMLHttpRequest();

    xhr.open('GET', url, true);



    xhr.onload = function (e) {

        if (this.status === 200) {

            results = JSON.parse(this.responseText);

            promise.resolve(results);

        }

    };



    xhr.onerror = function (e) {

        promise.reject(e);

    };



    xhr.send();

    return promise;

}



function loadTweets() {

    var container = document.getElementById('container');

    searchTwitter('#IE10').then(function (data) {

        data.results.forEach(function (tweet) {

            var el = document.createElement('li');

            el.innerText = tweet.text;

            container.appendChild(el);

        });

    }, handleError);

}

プロミセの原理
var defer = function () {

    var pending = [], value;

    return {

        resolve: function (_value) {

            value = _value;

            for (var i = 0, ii = pending.length; i < ii; i++) {

                var callback = pending[i];

                callback(value);

            }

            pending = undefined;

        },

        then: function (callback) {

            if (pending) {

                pending.push(callback);

            } else {

                callback(value);

            }

        }

    }

};

 
 
reference:
http://acgtofe.com/posts/2015/03/promise-from-zero/
http://www.infoq.com/cn/news/2011/09/js-promise/