Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

IMO promises and Bluebird made `async` obsolete.


They certainly did not, if for nothing other than `async.auto()`, which automatically runs a dependency graph of async functions.


A Promise/async/await implementation of 'async.auto' is trivial, as you can use the behavior of promises themselves to avoid solving the graph:

  async function Promise_auto(tasks) {
      const keys = Object.keys(tasks);
      const results = { };
      const taskPromises = { };
      function runTask(key) {
          if (!taskPromises[key]) {
              taskPromises[key] = (async () => {
                  let fn = tasks[key];
                  if (fn instanceof Array) {
                      const deps = fn.slice(0, -1);
                      fn = fn.slice(-1)[0];
                      await Promise.all(deps.map(runTask));
                  }
                  results[key] = await fn(results);
              })();
          }
          return taskPromises[key];
      }
      await Promise.all(keys.map(runTask));
      return results;
  }
Usage example (terms intentionally out of order):

  (async () => {
      const start = new Date();
      const results = await Promise_auto({
          write_file: ['get_data', 'make_folder', async (results) => {
              console.log('in write_file', results);
              await Promise.delay(1000);
              return 'filename';
          }],
          email_link: ['write_file', async (results) => {
              console.log('in email_link', results);
              await Promise.delay(1000);
              return {file: results.write_file, email: '[email protected]'};
          }],
          get_data: async () => {
              console.log('in get_data');
              await Promise.delay(1000);
              return [ 'data', 'converted to array' ];
          },
          make_folder: async () => {
              console.log('in make_folder');
              await Promise.delay(900);
              return 'folder';
          },
      });
      console.log('results = ', results);
      console.log(`It took ${(new Date() - start) / 1000} seconds`);
  })();


Here is a complex dependency graphs built with no nesting and no "special" methods, only a combination of `then` and `all`

  function test(name1, name2) {
    let user1 = User.find(name1)
    let user2 = User.find(name2)
    let post1 = user1.then(u => Posts.getLast(u.id))
    let post2 = user2.then(u => Posts.getLast(u.id))
    let comparison = Promise.all([post1, post2])
      .then(([p1, p2]) => DiffService.compare(p1, p2))
    let email1 = Promise.all([user1, comparison])
      .then(([u1, c]) => Email.send(comparison.text(), u1.email))
    let email2 = Promise.all([user2, comparison])
      .then(([u2, c]) => Email.send(comparison.text() ,u2.email))
    return Promise.all([email1, email2])
  }




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: