我怎么能用Promises重构这个回调地狱?

时间:2014-12-03 15:21:07

标签: javascript facebook-graph-api callback facebook-javascript-sdk promise

我有一段代码,可以使用facebook v1.0 API获取我朋友朋友的列表。

FB.api(
  {
    method: 'fql.query',
    query: 'SELECT uid, name, is_app_user FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=me()) AND is_app_user=1'
  },
  function (response) { // response contains a list of friends
    response.forEach(function(element){ // so for each friend
      FB.api(
        '/' + element.uid + '/friends',
        function (response) { // get a list of THEIR friends
          console.log(response); // and output them
        }
      );
    });
  }
);

我想重构此代码以使用更具可读性和可维护性的javascript promises和.then()语法。

为了澄清,我不喜欢在另一个FB.api电话中进行FB.api电话的想法。特别是如果我有多个这些,它们可以很深地嵌套。

我想使用promises,但我需要能够通过之前的response来电传递FB.api

我该怎么做?

理想情况下,它看起来像这样:

FB.api(
  {
    method: 'fql.query',
    query: 'SELECT uid, name, is_app_user FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=me()) AND is_app_user=1'
  },
  function(response){
    return response;
  })
.then(function(friends){
  friends.forEach(function(element){
    FB.api(
      '/' + element.uid + '/friends',
      function (response) {
        console.log(response);
      }
    );
  });
})

1 个答案:

答案 0 :(得分:1)

首先是一个小实用功能,用于宣传FB.api() ......

//jQuery
function FB_api(options) {
    return $.Deferred(function(dfrd) {
        return FB.api(options, dfrd.resolve);
    }).promise();
}

//Bluebird
function FB_api(options) {
    return new Promise(function(resolve, reject) {
        return FB.api(options, resolve);
    });
}

您可以类似地使用Q.jswhen.js ...

现在,你可以写......

FB_api({
    method: 'fql.query',
    query: 'SELECT uid, name, is_app_user FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=me()) AND is_app_user=1'
}).then(function(response) { // response contains a list of friends
    response.forEach(function(element) { // so for each friend
        FB_api('/' + element.uid + '/friends').then(function (response) { // get a list of THEIR friends
            console.log(response); // and output them
        });
    });
});