1

У меня есть блок кода, который получает список друзей моих друзей, используя API facebook v1.0.Как я могу реорганизовать этот обратный ад с обещаниями?

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 обещания и .then() синтаксис, который является более читаемым и ремонтопригодны.

Чтобы уточнить, мне не нравится идея сделать звонок FB.api в пределах другого звонка FB.api. Особенно, если у меня их много, они могут стать достаточно глубоко вложенными.

Я бы хотел использовать обещания, но мне нужно пройти в 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

Сначала небольшая функция полезности, которая служит для promisisfy 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.js или when.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 
     }); 
    }); 
});