0

Hi I am trying to write this function as a promise, I know how to write async functions in es6 but in es5 I am strugling This is wath I tried:

function getLeagueByID(sportID) {
      console.log(sportID);
      new Promise(function (resolve, reject) {
        RulesService.getLeagueByID(sportID)
          .then(function (results) {
            $scope.leagueById = results.data;
            getStatistics($scope.leagueById[0]);
          })
          .catch(function (err) {
            console.log(err);
          });
      });
    }

And how should I call this function latter?

Namysh
  • 3,717
  • 2
  • 9
  • 17
Emilis
  • 152
  • 1
  • 4
  • 21
  • 1
    Just FYI, your [currently-accepted answer](https://stackoverflow.com/a/63391145/157247) is a poor solution. It [uses an antipattern](https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it) and completely pointless `return` statements. **You** are the final arbiter of what solution you mark accepted; I'm mentioning this *only* so you don't get started using poor practices. – T.J. Crowder Aug 13 '20 at 09:07

3 Answers3

2

Three notes:

  1. Whenever you already have a promise (in this case, from RulesService.getLeagueByID) you don't need to use new Promise. Insetad, chain off the promise you already have. (More here.)
  2. Don't swallow errors; either allow them to propagate to the caller so the caller knows what's going on, or report them (not just to the console). Only handle errors at the highest level you can, which is usually an event handler that kicked off the overall process.
  3. You aren't returning anything from the function.

Addressing those, your function should probably look like this, which allows the caller to deal with errors:

function getLeagueByID(sportID) {
    console.log(sportID);
    return RulesService.getLeagueByID(sportID)
        .then(function(results) {
            $scope.leagueById = results.data;
            getStatistics($scope.leagueById[0]); // If this returns a promise or
                                                 // value you should return, add
                                                 // `return` in front of it
        });
    });
}

But if you don't expect the caller to handle errors, then:

function getLeagueByID(sportID) {
    console.log(sportID);
    return RulesService.getLeagueByID(sportID)
        .then(function(results) {
            $scope.leagueById = results.data;
            getStatistics($scope.leagueById[0]); // If this returns a promise or
                                                 // value you should return, add
                                                 // `return` in front of it
        })
        .catch(function (err) {
            // Do something other than just `console.log` here, in most cases; for instance, show an
            // error to the user
        });
    });
}

And how should I call this function latter?

That depends on what's calling the function. As with the above, if it's something that's expecting its caller to handle errors, then:

return getLeagueByID(someSportId);

If it's an event handler or similar, and so doesn't expect its caller to handle errors, then:

getLeagueByID(someSportId)
    .catch(function (err) {
        // Do something other than just `console.log` here, in most cases; for instance, show an
        // error to the user
    });
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
2

As RulesService.getLeagueByID returns a promise, you can just return that.

function getLeagueByID(sportID) {
  console.log(sportID);
  return RulesService.getLeagueByID(sportID)
     .then(function (results) {
        $scope.leagueById = results.data;
        getStatistics($scope.leagueById[0]);
     })
     .catch(function (err) {
        console.log(err);
     });
}

To call it

getLeagueByID(id)
   .then(function(){HANDLER CODE});
Mathias Haser
  • 21
  • 1
  • 1
0
function getLeagueByID(sportID) {
      console.log(sportID);
      return new Promise(function (res, rej) { //you need to return here
        RulesService.getLeagueByID(sportID)
          .then(function (results) {
            $scope.leagueById = results.data;
            res(getStatistics($scope.leagueById[0])); //resolve 
            return; //return to avoid unintended side effects
          })
          .catch(function (err) {
            console.log(err);
            rej(err) //need to reject
            return; //return to avoid unintended side effects
          });
      });
    }

A promise is just like an async method. To use this, you can

await getLeagueByID(sportID)

in an async method, or you can use

getLeagueByID(sportID).then(r=>console.log(r)).catch(e=>console.log(e)) 

essentially 'forking' the current thread.

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
  • This is an example of the explicit promise creation antipattern. More: [*What is the explicit promise construction antipattern and how do I avoid it?*](https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it) – T.J. Crowder Aug 13 '20 at 08:32
  • The unintended side effect of this function is when you batch multiple promises together, and each of those methods will continue to run even after your wrapper has thrown or returned up the chain of command. To avoid this from happening, you can explicitly return out of the promise, thus a promise will only reject or resolve only once and thus, can be used with promise all or raw thread batching using thread pointers. – Anthony Moon Beam Toorie Aug 13 '20 at 08:37
  • As per your note regarding promise chaining. You can achieve promise chaining using this technique. You can not achieve promise chaining using .then catch system, you can only promise join. You can chain using this technique and using async await. – Anthony Moon Beam Toorie Aug 13 '20 at 08:39
  • I'm afraid I don't understand what you're trying to say there. Using `.then`/`.catch` is *the* fundamental way you chain promises. Again, please see the linked question's answers. This isn't a controversial area. – T.J. Crowder Aug 13 '20 at 08:41
  • *"`return; //return to avoid unintended side effects`"* Those returns do literally nothing whatsoever. – T.J. Crowder Aug 13 '20 at 08:43
  • I will try to get an example later tonight – Anthony Moon Beam Toorie Aug 13 '20 at 08:44
  • We may be using different terminology from one another, but the assertion that using `new Promise` here is anything but pointless is incorrect. This is the classic antipattern. – T.J. Crowder Aug 13 '20 at 08:47
  • No problem. I also liked your response because I thought it was well written. I will have a look and reply with a more thoughtful response. – Anthony Moon Beam Toorie Aug 13 '20 at 08:53
  • You are right in this specific example, both return statements do nothing. But in general, they can be used for clarity, are considered good practice, and can save CPU cycles. The information can be located here : https://stackoverflow.com/questions/32536049/do-i-need-to-return-after-early-resolve-reject I would agree with you that in this case, those return statements are not necessary. – Anthony Moon Beam Toorie Aug 13 '20 at 09:07
  • With regard to my previous comment regarding thread batching, this does not relate and I was wrong. The reason? If you batch multiple threads, and await on each one of the thread pointers (similar to promise all), all of those threads will eventually resolve or reject, and if two of those promises reject, then you will receive an error that you have not handled all your errors properly for promises. You would never do this in reality, as you would use promise all, but it is good to know how to do things in different ways. Will come back to this at some point with more thoughts. – Anthony Moon Beam Toorie Aug 13 '20 at 09:09
  • *"But in general...are considered good practice"* Of course it's good practice to use a `return` *when it skips code you don't need to run* (as shown in the accepted answer there). Using `return`s when they *don't* do something is not good practice. *"and can save CPU cycles"* Only, again, when they actually have an effect. Otherwise, they're just extra code to read (and in this case, puzzle over). – T.J. Crowder Aug 13 '20 at 09:12
  • There is no threading involved here at all, and promises have **nothing** to do with threads. – T.J. Crowder Aug 13 '20 at 09:13
  • Yes but promise are abstractions on thread functionality, doing tasks asynchronously, and forking tasks in general, and work almost identically in almost every conceptual way. – Anthony Moon Beam Toorie Aug 13 '20 at 09:16
  • *"promise are abstractions on thread functionality"* No, they aren't. They're [abstractions of asynchronous operations](https://promisesaplus.com/). While that may involve threads (for instance, a browser's I/O thread as separate from the thread it runs JavaScript on), it may also involve something else entirely (a user interaction, ...). Threads and promises are very, very different. With that, I have to step away from this and get some work done. Happy coding. – T.J. Crowder Aug 13 '20 at 09:22