1

In AngularJS - mixing HTTP and custom promises with recursion I had posted a question about fixing a piece of code that involved returning promises and it was pointed out to me that I was unnecessarily creating wrapper promises. In following the suggestions, I landed up with a much cleaner code. I do have a followup question: In a situation like the below (made up example) where I ned to mix promise code with non-promise code, I don't see an option but to construct my own promise using $q.defer() and returning d.promise at the end. Is there a better/recommended way? And is it okay to mix my custom promise with functions that return their own promise?

function my_func(use_promise) {
  var d = $q.defer();

  if (!use_promise) {
     x = do_a_sync_function_that_takes_time();
     d.resolve(x)
     return d.promise; 
  } else {
     return do_a_promise_function_that_takes_time()
     .then (function(data) {
        return (data); // this gets promisified as we are in .then
     })
     .catch(function (err) {return "Error ";});
  }
  return d.promise;
}
user1361529
  • 2,667
  • 29
  • 61
  • Good rule of thumb is if a function is going to return promise for some condition is return promise for all conditions – charlietfl Oct 25 '20 at 00:40

1 Answers1

1

To convert a synchronous value to a promise, simply use $q.when or $q.resolve:

function my_func(use_promise) {
  ̶v̶a̶r̶ ̶d̶ ̶=̶ ̶$̶q̶.̶d̶e̶f̶e̶r̶(̶)̶;̶

  if (!use_promise) {
     var x = do_a_sync_function_that_takes_time();
     ̶d̶.̶r̶e̶s̶o̶l̶v̶e̶(̶x̶)̶
     return $q.when(x); 
  } else {
     return do_a_promise_function_that_takes_time()
     .then (function(data) {
        return (data); // this gets promisified as we are in .then
     })
     .catch(function (err) {return "Error ";});
  }
  ̶r̶e̶t̶u̶r̶n̶ ̶d̶.̶p̶r̶o̶m̶i̶s̶e̶;̶
}

For more information, see

georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • In your code above for the sync function the return comes after the sync function. Do we not need to return a promise immediately? I’ve seen situations where the calling function complains of ‘cannot execute .then() for undefined’ (or similar) when a promise isn’t returned immediately. – user1361529 Oct 24 '20 at 23:25
  • The JavaScript platform is single-threaded. Code subsequent to the invocation of the `my_func` function will not execute until the function that takes time finishes its operation. One can put the execution of the time intensive function onto a later tick of the JavaScript platform with the [`$timeout` service](https://docs.angularjs.org/api/ng/service/%24timeout). Keep in mind that the JavaScript platform is single-threaded, so no matter when the time intensive function starts, the platform will hang while the time intensive function executes. – georgeawg Oct 25 '20 at 02:54
  • One can use the [Web Workers API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) to run a script operation in a background thread separate from the main execution thread of a web application. The advantage of this is that laborious processing can be performed in a separate thread, allowing the main (usually the UI) thread to run without being blocked/slowed down. See also [Running code inside another thread in javascript](https://stackoverflow.com/questions/17613396/running-code-inside-another-thread-in-javascript). – georgeawg Oct 25 '20 at 02:54
  • How would you modify the above to immediately return a promise in both cases? I’m a little queasy about relying on the single threadedness condition. – user1361529 Oct 25 '20 at 11:46
  • The code in this answer will always return a promise.It will never return a value of `undefined`. In the case of the synchronous time intensive function, it will eventually return the promise, it the time intensive function is truly synchronous. – georgeawg Oct 25 '20 at 19:25