I found one article that kind of explains how to queue up asynchronous operations, but it's rather vague in that it says if you return a "promise-like" object from a then function, it will make the next then wait for it to complete. I don't know what "promise-like" means, so I took a stab at this (see code below), and it works, but I'm not sure if this is the correct way to go about doing this or not.
let promise = new Promise(function (resolve, reject) {
  someAsyncOperation(function () {
    resolve({done: true});
  });
});
promise.then(function (val) {
  return new Promise(function (resolve, reject) {
    anotherAsyncOperation(function () {
      resolve({doneAgain: true});
    });
  });
}).then(function (val) {
  // This only occurs after the anotherAsyncOperation is done
});
 
     
    