[gist]Why Promises will make async easy


from http://oyanglul.us

What is Promises

Promise is a proxy for a value not knowing when its creation time. It provide 2 Methods then and catch, which return promise so they can be chained.

Promise.prototype.then(onFulfilled, onRejected)

Appends fullfillment and rejection handlers to the promise, and returns a new promise resolving to the return value of the called handler.

Promise.prototype.catch(onRejected)

Appends a rejection handler callback to the promise, and returns a new promise resolving to the return value of the callback if it is called, or to its original fulfillment value if the promise is instead fulfilled.

Why Promises

there are so many reasons you should use promise in you client rich project if you are not using any MV* frameworks.

有许多理由你将会需要用到 Promises. 好吧先来解释一下什么是 Promises 。 这类似于我们经常使用的 jQuery.ajax() 返回的那个玩意 – Deferreds.

比如想要在对 ajax 请求来的数据做加工

  $.ajax("yourdata.url").then(function(data){
      // do something with your data
  })

对等待多个请求返回的数据做加工

  $.when($.ajax("yourdata1.url"),$.ajax("yourdata2.url")).then(function(data){
    // do something with these data                                                           
  })

好吧如果这么说 Promises 不是什么新玩意, jQurey 早都有了, 为什么还要用什么 q.js.

Diference between Deferreds and Promises

常用的 Promises 库为:

他们都执行同一个标准 Promises/A+, 而 jQuery 的 Deferreds 虽然也做类似的事情,但是并不兼容 Promises/A+. 而 Chrome 32 已经原生支持了这一标准,Firefox 还在 Beta 阶段。

How to use

I’ve chose  Q as my Promises implement library. Take GIRA as example, GIRA will request data from Github API and then manipulate them into the page I want. So basiclly two step but actually if you want have more complex data to combind, Promise will make your life easier.

What is the old way looks like

  $.getJSON(this.REPO_BASE, function(issues){
      $.getJSON(this.REPO_BASE + 'user/repos', function(labels){
        // do something with issues and labels
          renderIssueAndLabel();
      })
  })   
       

seems like dump code isn’t it. now see what eligent will be

Promisify Ajax Request

I just promisify all Github API function to make them return Promises.

Say I want all the label of my project from Github API. simply parse jquery deferred in to Promise.

Github.prototype ={
...
    getLabels: function(){
        return Q($.ajax({
            url: 'github.issues.labels.url'
        }));
    }
...
}

Thenable

          Gira.prototype.groupIssuesByLabels = function() {
            return Q.all([this.github.getIssues(this.owner,this.repo,this.milestone),this.github.getLabels(this.owner,this.repo)])
                  .then(function(data){
          //combind these Issues and Labels
                  },function(error){
                      // promise not fullfill
                  })
          }

since then() in =groupIssuesByLabels=  will also return a thenable object. So you can do this then:

  gira.groupIssuesByLabes().then(renderIssues,errorHandler);

Error Handling

I think this is the best and my favor part of Promise

      Q('some data').then(function(data){
          return something1(data);
      }).then(function(data){
          return something2(data);
      }).catch(function(error){
          // if any of Q(), something1() or something2() goes wrong.
      }).then(function(){
          // do this any way
          doanyway();
    })

this is the same as:

  function doanyway(){
      
  }
  function something1(data, callback){
      try{
          //do something
      }catch(function(error){
          doanyway();
      })
  
      callback(data);
  }
  function something2(data){
    try{
          //do something
      }catch(function(error){
          doanyway();
      })
  
  }
  try{
      $.getJSON('some data', function(data){
          something1(data, something2)
      }) 
  }catch(function(error){
      // 
  })


发表评论

电子邮件地址不会被公开。

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>