I'm learning how to use Promises. I have the following functions that returns the "i"th xkcd comic title as a Promise:
var xkcd = function(i) {
  return new Promise(
    function(resolve, reject) {
      var tempurl = 'https://www.xkcd.com/' + i;
      request(tempurl, function(error, response, body) {
        if (error) reject(error);
        var $ = cheerio.load(body);
        resolve($('title').text() + '\n');
      });
    });
};
If i want to get the first 4 titles, I'm chaining my .then() as such:
var result = '';
xkcd(1)
  .then(fullfilled => {
    result += fullfilled;
  })
  .then(() => xkcd(2))
  .then(fullfilled => {
    result += fullfilled;
  })
  .then(() => xkcd(3))
  .then(fullfilled => {
    result += fullfilled;
  })
  .then(() => xkcd(4))
  .then(fullfilled => {
    result += fullfilled;
    console.log(result);
  });
Is there a more elegant way to do this without chaining this many "then"s? Say if i want to get the first 50 comic titles, i'll have to chain a lot of "then"s.
I can do it without using Promises using recursive callbacks:
function getXKCD(n) {
  var i = 1;
  (function getURL(i){
    var tempurl = 'https://www.xkcd.com/' + i;
    request(tempurl, function(error, response, body) {
      if (error) console.log('error: ' + error);
      var $ = cheerio.load(body);
      //prints the title of the xkcd comic
      console.log($('title').text() + '\n');
      i++;
      if (i <= n) getURL(i);
    });
  })(i);
}
getXKCD(4);
But I'm interested to know if I can do the same with Promises. Thank you.
You can push the promises to an array, and then return Promise.all, which would resolve when all the promises have resolved, something like
function getXKCD(_start, _end) {
  if (_end >= _start) return Promise.reject('Not valid!');
  var promises = [];
  (function rec(i) {
    var p = new Promise(function(resolve, reject) {
      request('https://www.xkcd.com/' + i, function(error, response, body) {
        if (error !== null) return reject(error);
        if (i <= _end) rec(++i);
        let $ = cheerio.load(body);
        resolve($('title').text());
      });
    });
    promises.push(p);
  })(_start);
  return Promise.all(promises);
}
getXKCD(1, 50).then(res => { /* All done ! */ }).catch( err => { /* fail */ })
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With