title: How to use jQuery Deferred functionality instead of async.waterfall?
body: <p>I have a chain of function calls and use async.waterfall. It works like a charm. But I'd like to do it with jQuery Deferred. How to transform my code?</p>
  
  <p>The example from jQuery site is like this. Both results are passed to <code>done</code> function:</p>
  
  <pre><code>$.when( $.ajax( "/page1.php" ), $.ajax( "/page2.php" ) ).done(function( a1, a2 ) {
    // a1 and a2 are arguments resolved for the page1 and page2 ajax requests, respectively.
    // Each argument is an array with the following structure: [ data, statusText, jqXHR ]
    var data = a1[ 0 ] + a2[ 0 ]; // a1[ 0 ] = "Whip", a2[ 0 ] = " It"
    if ( /Whip It/.test( data ) ) {
      alert( "We got what we came for!" );
    }
  });
  </code></pre>
  
  <p>But my code is different. I need to pass a callback to every step of a <code>waterfall</code> and I have <code>if</code>s in callbacks. How to implement it with jQuery? Is it possible?</p>
  
  <pre><code>async.waterfall([
          function(cb) {
              VK.Api.call('users.get', {user_ids: res.session.mid, fields: fields}, function(userDataRes) {
                  cb(null, userDataRes);
              });
          },
          function(userDataRes, cb) {
              if(userDataRes.response[0].city) {
                  VK.Api.call('database.getCitiesById', {city_ids: userDataRes.response[0].city}, function(cityDataRes) {
                      cb(null, userDataRes, {city: cityDataRes.response[0].name});
                  });
              }
              else {
                  cb(null, userDataRes, {});
              }
          },
          function(userDataRes, cityDataRes, cb) {
              if(userDataRes.response[0].country) {
                  VK.Api.call("database.getCountriesById", {country_ids: userDataRes.response[0].country}, function(countryDataRes) {
                      cb(null, userDataRes, cityDataRes, {country: countryDataRes.response[0].name});
                  });
              }
              else {
                  cb(null, userDataRes, {}, {});
              }
          },
          function(userDataRes, cityDataRes, countryDataRes, cb) {
              var resObj = $.extend(true, {}, userDataRes.response[0], cityDataRes, countryDataRes);
              cb(null, resObj);
          },
      ],
      function(err, res) {
          console.log("res::: ", res);
      }
  );
  </code></pre>
  
  <p><strong>UPD 1:</strong></p>
  
  <p>So, I've implemented a solution, but it doesn't work as expected. There is an asynchronous API function call in <code>.then()</code> and jQuery deferred flow is broken there. I don't know how to make a <code>.then()</code> function as an API callback.</p>
  
  <pre><code>var dfr = $.Deferred();
  
  dfr.then(function(val) {
  
      // THIS is an asynchronous API function call. And its callback returns result that is passed to the next .then()
      // But jQuery deferred flow doesn't follow this API call. 
      // It goes along to the next .then ignoring this API call.
      // How to make it enter this API call and be returned from a API's callback.
      VK.Api.call('users.get', {user_ids: res.session.mid, fields: fields}, function(userDataRes) {
          // cb(null, userDataRes);
          console.log("countryDataRes: ", userDataRes);
          return userDataRes;
      });
  }).
  then(function(userDataRes) {
      console.log("countryDataRes: ", userDataRes);
      if(userDataRes.response[0].city) {
          VK.Api.call('database.getCitiesById', {city_ids: userDataRes.response[0].city}, function(cityDataRes) {
              // cb(null, userDataRes, {city: cityDataRes.response[0].name});
              return [userDataRes, {city: cityDataRes.response[0].name}];
          });
      }
      else {
          // cb(null, userDataRes, {});
          return [userDataRes, {}];
      }
  }).
  then(function(aRes) {
      if(aRes[0].response[0].country) {
          VK.Api.call("database.getCountriesById", {country_ids: aRes[0].response[0].country}, function(countryDataRes) {
              // cb(null, userDataRes, cityDataRes, {country: countryDataRes.response[0].name});
              return [aRes[0], aRes[1], {country: countryDataRes.response[0].name}];
          });
      }
      else {
          cb(null, aRes[0], {}, {});
      }
  }).
  then(function(aRes) {
      var resObj = $.extend(true, {}, aRes[0].response[0], aRes[1], aRes[2]);
      console.log("cityDataRes: ", aRes[1]);
      console.log("countryDataRes: ", aRes[2]);
      cb(null, resObj);
      return resObj;
  }).
  done(function(res) {
      console.log("res::: ", res);
  });
  
  dfr.resolve();
  </code></pre>