Giter VIP home page Giter VIP logo

Comments (15)

topaxi avatar topaxi commented on May 15, 2024 10

Regenerator uses the global Promise object, this means you need to replace window.Promise with RSVP.Promise somewhere before any async function gets executed.

Example:
app/initializers/promise.js

import RSVP from 'rsvp'

export default {
  name: 'promise',
  initialize() {
    window.Promise = RSVP.Promise
  }
}

This probably won't work anymore once native async functions land though.

from rfcs.

rwjblue avatar rwjblue commented on May 15, 2024 5

Ember 3.4 has dropped the auto run assertion, and using async functions in "production" code is quite feasible. There are still some rough edges, but overall it works very well.

Closing this now, as "implemented".

from rfcs.

caseywatts avatar caseywatts commented on May 15, 2024 3

I've been trying to use async/await in both app code and test code this week, and I ran into this issue too.

I think I'm going to avoid using async/await in app code for now. I definitely don't want to type Ember.run everywhere, and patching window.Promise to use the RSVP version (which includes the Ember.run) would only be a ~short-term fix. It does work currently on a few promises in our app that aren't Ember-y, but it's hard to keep track of which are which so we might just abandon using async/await in app code generally.

I could maybe imagine a parallel version of await, called something similar (like awaiit?) that acts like await but also calls the Ember.run loop. Just like RSVP does for Promises. But I'm not sure how useful that would be unless we could get it to behave like await inline too, like in const thing = await asyncThing();,

Async/await still helps a lot in tests, though! :)

I have some more notes on this, here: https://gist.github.com/caseywatts/7c01654f74fbe402dfaadfa144965adb

from rfcs.

rwjblue avatar rwjblue commented on May 15, 2024 2

I think a better way to manage async/await feature is needed.

I don't think this is related to async/await really, the main issue is with the set that is done outside of the run loop. Writing the same code in a promise style would have the same issue.

To me the real question is: can we avoid requiring Ember.set / this.set to be wrapped in a run loop? Right now the answer is no, but it is something that we have discussed at length and would like to find a path towards.

from rfcs.

dfreeman avatar dfreeman commented on May 15, 2024 1

Writing the same code in a promise style would have the same issue.

I was under the impression RSVP would create a run loop (even in testing mode) when executing handlers after one of its promises settled. Is that a bad assumption?

https://ember-twiddle.com/e2721848f818029dd39873e3da88870c?openFiles=tests.unit.runloop-test.js%2C

from rfcs.

GCorbel avatar GCorbel commented on May 15, 2024 1

I don't have any problem with the same code in promise version. Here is the code :

    clone(model) {
      model.clone().then(clone=> {
        clone.set('name', clone.get('name') + ' - copie');
        clone.set('activity', model.get('activity'));
        this._nestedSave(clone, 'groups');
      });
    }

from rfcs.

sukima avatar sukima commented on May 15, 2024 1

Thank you @caseywatts I just got bit with this today. Thank you for commenting! This issue of async/await is the core reason for my RFC to ember-concurrency concerning exposing a coroutine API.

Sadly neither async/await nor a coroutine exposed from e-c is in the works. I think the next step would be to make an addon that wraps tj/co.

from rfcs.

sukima avatar sukima commented on May 15, 2024 1

For a work around there is an addon: https://www.npmjs.com/package/ember-co

from rfcs.

GCorbel avatar GCorbel commented on May 15, 2024

I have to investigate a little bit more because it seems to work on another project. My function model.clone use promises and I have to check if I can replace it by async/await functions.

from rfcs.

GCorbel avatar GCorbel commented on May 15, 2024

@topaxi I think you're right. It works with your initializer. I will do more tests.

from rfcs.

GCorbel avatar GCorbel commented on May 15, 2024

There is an issue with ember-cli-page-object. In a test, I have await page.submit(); and it doesn't work but await click('#submit');. It's probably because of this line.

What I can see is wait callback is not triggered. For example, with :

wait(()=> {
  console.log(1);
});

I can't show "1" in the console. wait is waiting for the last promise. I don't understand why it doesn't work.

from rfcs.

jrjohnson avatar jrjohnson commented on May 15, 2024

This bit me while attempting to build an async computed property like:

foo: computed('bar', async function(){
  return await this.get('bar');
})

It works surprisingly well and renders great, but breaks any tests with the "wrap any code with asynchronous side-effects" error.

Adopting @topaxi's solution of replacing the global Promise with RSVP.Promise solves the issue. I assume RSVP.Promise has some magic to notify qunit of asynchronous work to come?

This would seem to be the kind of issue that needs to be addressed at the framework level before the use of async / await picks up momentum. I've seen several blog posts advocating its use with Ember already; most recently https://spin.atomicobject.com/2016/12/29/async-await-ember-project/ which was listed in Ember Weekly a few weeks ago.

from rfcs.

theseyi avatar theseyi commented on May 15, 2024

Hey @rwjblue any potential updates on this issue without resorting to overriding the global Promise object per @topaxi 's solution? Teammate just encountered a similar scenario. Running the snippet below in an async/await raises the same exception, but changing it to a Promise based func, results in the test executing as expected.

promise: works

 authenticateUser() {
      const { username, password, authenticator } = getProperties(this, ['username', 'password', 'authenticator']);
      const setAuthFlag = () => {
        if (!(this.isDestroying || this.isDestroyed)) {
          set(this, isAuthenticatingFlag, false);
        }
      }

      // Set the isAuthenticatingFlag on the host object, and default error message string to empty
      setProperties(this, { [isAuthenticatingFlag]: true, errorMessage: '' });

      return get(this, 'session').authenticate('authenticator', { username, password }).then(() => {
        setAuthFlag();
      }).catch(({ error = errorMessage }) => {
        set(this, 'errorMessage', error);
        setAuthFlag();
      });
    }
  }

versus:
async/await: does not work

    async authenticateUser() {
      const { username, password, authenticator } = getProperties(this, ['username', 'password', 'authenticator']);
      let result;
      // Set the isAuthenticatingFlag on the host object, and default error message string to empty
      setProperties(this, { [isAuthenticatingFlag]: true, errorMessage: '' });

      try {
        // Send the username and password to the specified Ember Auth authenticator
        result = await get(this, 'session').authenticate('authenticator', { username, password });
      } catch ({ error = errorMessage }) {
        set(this, 'errorMessage', error);
      } finally {
        if (!(this.isDestroying || this.isDestroyed)) {
          set(this, isAuthenticatingFlag, false);
        }
      }

      return result;
    }

from rfcs.

sukima avatar sukima commented on May 15, 2024

The discuss discussion here seems more relevant now; suggesting that this issue is fixed in Ember 3.0+

Can anyone confirm?

from rfcs.

dfreeman avatar dfreeman commented on May 15, 2024

I believe that post suggests that the issue can be fixed in 3.0+, but that so far BackburnerJS/backburner.js#332 has struck any time someone has attempted it.

from rfcs.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.