2

I have a project using ES6 and AngularJS, and as far as I found, AngularJS $q promises is synchronous but ES6 promises not. Right? The question is, what are the differences? and when should I use $q or ES6? I know what is the difference between Synchronous and Asynchronous, but got confused between new Promise and AngularJS $q.

raise from here

GeoCom
  • 1,290
  • 2
  • 12
  • 33
  • What do you mean by "$q promises is synchronous"? I don't know Angular and i don't want to, but even looking at their docs didn't help me much. Isn't the whole point of promises to help us write asynchronous code (and avoid callback hell)? – helb Oct 24 '17 at 22:07
  • 1
    `Right?` - wrong. Promises are by definition asynchronous. The difference between $q and ES6 Promises is that $q Promises (at least a few months back, could be fixed now) are not quite Promise/A+ spec compliant – Jaromanda X Oct 24 '17 at 22:19
  • `$q Promises (at least a few months back) are not quite Promise/A+ spec compliant` what does it mean? – GeoCom Oct 24 '17 at 22:20
  • @JaromandaX $q promises wrap new Promise – charlietfl Oct 24 '17 at 22:24
  • @charlietfl - that may well be the case now, but it wasn't a few months back – Jaromanda X Oct 24 '17 at 22:26
  • @Milban - it means that $q **was** a Promise implementation that wasn't quite compliant with [this specification](https://promisesaplus.com/) – Jaromanda X Oct 24 '17 at 22:27
  • @charlietfl Yes. And `new Promise` is... [$q promise](https://github.com/angular/angular.js/blob/v1.6.6/src/ng/q.js#L315-L317). – Estus Flask Oct 24 '17 at 22:39

1 Answers1

2

The statement about $q synchronicity applies to unit tests with ngMock in the first place.

$q promises are capable of being synchronous in production:

let foo;

$q.resolve().then(() => { foo = 1 });
$rootScope.$digest();
console.log(foo === 1);

And they are supposed to be synchronous in unit tests, because all AngularJS services that are responsible for asynchronous behaviour ($timeout, $http, etc) are mocked with ngMock in order to make tests fully synchronous:

it('...', inject(($q) => {
    let foo;

    $q.resolve().then(() => { foo = 1 });
    $rootScope.$digest();
    expect(foo).toBe(1);
}));

While ES6 promises are asynchronous by design, and then callback runs on next tick:

it('...', (done) => {
    let foo;

    Promise.resolve(1).then(() => {
      foo = 1;
      expect(foo).toBe(1);
    })
    .then(done, done.fail);
});
Estus Flask
  • 206,104
  • 70
  • 425
  • 565