Skip to main content
incorporating comment
Source Link
Patrick M
  • 256
  • 2
  • 7

A promise is a wrapper for a callback function. In many libraries, this is called a .then() function. In simplest terms, a promise waits for a return, and then calls the function passed to then(). The simplicity was confusing for me in the beginning, so lets use your example. Let me upgrade x and y to functions. If they are functions that return promises (as many asynch heavy libraries do, like a NodeJS database accessor), this becomes trivial.

If you repeat that code for the y() function, you get back to where you can use Q.all() to wait for both x() and y() to complete.

A promise is a wrapper for a callback function. In many libraries, this is called a .then() function. In simplest terms, a promise waits for a return, and then calls then. The simplicity was confusing for me in the beginning, so lets use your example. Let me upgrade x and y to functions. If they are functions that return promises (as many asynch heavy libraries do, like a NodeJS database accessor), this becomes trivial.

If you repeat that code for the y() function, you get back to where you can use Q.all to wait for both x and y to complete.

A promise is a wrapper for a callback function. In many libraries, this is called a .then() function. In simplest terms, a promise waits for a return, and then calls the function passed to then(). The simplicity was confusing for me in the beginning, so lets use your example. Let me upgrade x and y to functions. If they are functions that return promises (as many asynch heavy libraries do, like a NodeJS database accessor), this becomes trivial.

If you repeat that code for the y() function, you get back to where you can use Q.all() to wait for both x() and y() to complete.

added syntax-highlighting
Source Link
Deduplicator
  • 9.3k
  • 5
  • 33
  • 53
Q.all([x(), y()]).then(function(results) {
  // Do some stuff with results, which is an enumerable collection containing
  // the in-order results of the promises passed in.
});
Q.all([x(), y()]).then(function(results) {
  // Do some stuff with results, which is an enumerable collection containing
  // the in-order results of the promises passed in.
});
// Upgrade x into a promise returning function
function promise_x(/*x params...*/) {
  return Q.fcall(x(/*x params...*/));
}

// Upgrade x into a promise with a deferred
// Useful if you have some standard error handling specific to x-like functions
function defer_x(/*x params...*/) {
  var deferred = Q.defer();
  // If x is asynch, assume it takes a callback function with params of (error, result)
  x(/*x params...*/), function (error, result) {
    if (error) {
      deferred.reject(new Error(error));
    } else {
      // If you have some processing to do with the result of x (and not y), you can do
      // it here and return the modified result instead
      deferred.resolve(result);
    }
  });
  return deferred.promise;
}
// Upgrade x into a promise returning function
function promise_x(/*x params...*/) {
  return Q.fcall(x(/*x params...*/));
}

// Upgrade x into a promise with a deferred
// Useful if you have some standard error handling specific to x-like functions
function defer_x(/*x params...*/) {
  var deferred = Q.defer();
  // If x is asynch, assume it takes a callback function with params of (error, result)
  x(/*x params...*/), function (error, result) {
    if (error) {
      deferred.reject(new Error(error));
    } else {
      // If you have some processing to do with the result of x (and not y), you can do
      // it here and return the modified result instead
      deferred.resolve(result);
    }
  });
  return deferred.promise;
}
MyOverallFunction() {
  Q.all([x(), y()]).then(function(results) {
    // Do some stuff with results, which is an enumerable collection containing
    // the in-order results of the promises passed in.
    var combinedResult = synchronousFunction(result[0], result[1]);
    anotherAsyncPromiseFn(combinedResult)
      .then(function(result)) {
        return result;
      });
  }).then(function(result) {
     // Here, result is the return value of anotherAsyncPromiseFn
  }).error(function(err) {
     // This is the cool part. Any error from x, y, synchronousFunction, or
     // anotherAsyncPromiseFn will propagate to here. If you don't want to
     // handle it, just re-throw it (after logging it, if you prefer).
  });
}
MyOverallFunction() {
  Q.all([x(), y()]).then(function(results) {
    // Do some stuff with results, which is an enumerable collection containing
    // the in-order results of the promises passed in.
    var combinedResult = synchronousFunction(result[0], result[1]);
    anotherAsyncPromiseFn(combinedResult)
      .then(function(result)) {
        return result;
      });
  }).then(function(result) {
     // Here, result is the return value of anotherAsyncPromiseFn
  }).error(function(err) {
     // This is the cool part. Any error from x, y, synchronousFunction, or
     // anotherAsyncPromiseFn will propagate to here. If you don't want to
     // handle it, just re-throw it (after logging it, if you prefer).
  });
}
Q.all([x(), y()]).then(function(results) {
  // Do some stuff with results, which is an enumerable collection containing
  // the in-order results of the promises passed in.
});
// Upgrade x into a promise returning function
function promise_x(/*x params...*/) {
  return Q.fcall(x(/*x params...*/));
}

// Upgrade x into a promise with a deferred
// Useful if you have some standard error handling specific to x-like functions
function defer_x(/*x params...*/) {
  var deferred = Q.defer();
  // If x is asynch, assume it takes a callback function with params of (error, result)
  x(/*x params...*/), function (error, result) {
    if (error) {
      deferred.reject(new Error(error));
    } else {
      // If you have some processing to do with the result of x (and not y), you can do
      // it here and return the modified result instead
      deferred.resolve(result);
    }
  });
  return deferred.promise;
}
MyOverallFunction() {
  Q.all([x(), y()]).then(function(results) {
    // Do some stuff with results, which is an enumerable collection containing
    // the in-order results of the promises passed in.
    var combinedResult = synchronousFunction(result[0], result[1]);
    anotherAsyncPromiseFn(combinedResult)
      .then(function(result)) {
        return result;
      });
  }).then(function(result) {
     // Here, result is the return value of anotherAsyncPromiseFn
  }).error(function(err) {
     // This is the cool part. Any error from x, y, synchronousFunction, or
     // anotherAsyncPromiseFn will propagate to here. If you don't want to
     // handle it, just re-throw it (after logging it, if you prefer).
  });
}
Q.all([x(), y()]).then(function(results) {
  // Do some stuff with results, which is an enumerable collection containing
  // the in-order results of the promises passed in.
});
// Upgrade x into a promise returning function
function promise_x(/*x params...*/) {
  return Q.fcall(x(/*x params...*/));
}

// Upgrade x into a promise with a deferred
// Useful if you have some standard error handling specific to x-like functions
function defer_x(/*x params...*/) {
  var deferred = Q.defer();
  // If x is asynch, assume it takes a callback function with params of (error, result)
  x(/*x params...*/), function (error, result) {
    if (error) {
      deferred.reject(new Error(error));
    } else {
      // If you have some processing to do with the result of x (and not y), you can do
      // it here and return the modified result instead
      deferred.resolve(result);
    }
  });
  return deferred.promise;
}
MyOverallFunction() {
  Q.all([x(), y()]).then(function(results) {
    // Do some stuff with results, which is an enumerable collection containing
    // the in-order results of the promises passed in.
    var combinedResult = synchronousFunction(result[0], result[1]);
    anotherAsyncPromiseFn(combinedResult)
      .then(function(result)) {
        return result;
      });
  }).then(function(result) {
     // Here, result is the return value of anotherAsyncPromiseFn
  }).error(function(err) {
     // This is the cool part. Any error from x, y, synchronousFunction, or
     // anotherAsyncPromiseFn will propagate to here. If you don't want to
     // handle it, just re-throw it (after logging it, if you prefer).
  });
}
language -> answer makes a lot more sense, doesn't it?
Source Link
Patrick M
  • 256
  • 2
  • 7

Ultimately, the tools that are at your disposal depend upon your language and environment. Promises have been implemented in more languages than just JS, and another closely related idiom from async/functional programming is Futures. Admittedly, if your language of choice does not havedoes not have a Promise library, this languageanswer will be pretty useless to you, but hopefully you at least find it interesting.

Ultimately, the tools that are at your disposal depend upon your language and environment. Promises have been implemented in more languages than just JS, and another closely related idiom from async/functional programming is Futures. Admittedly, if your language of choice does not have a Promise library, this language will be pretty useless to you, but hopefully you at least find it interesting.

Ultimately, the tools that are at your disposal depend upon your language and environment. Promises have been implemented in more languages than just JS, and another closely related idiom from async/functional programming is Futures. Admittedly, if your language of choice does not have a Promise library, this answer will be pretty useless to you, but hopefully you at least find it interesting.

JDefered promise library
Source Link
Patrick M
  • 256
  • 2
  • 7
Loading
Source Link
Patrick M
  • 256
  • 2
  • 7
Loading