Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rendering (actually not rendering, just task) could happen multiple times (in multiple micro tasks), getterThrottle could cache wrong value #1

Open
3cp opened this issue May 25, 2018 · 3 comments

Comments

@3cp
Copy link
Member

3cp commented May 25, 2018

When clicking "update" button, local i is updated, upper level j is updated (ea calls subscribers in sync, not async mode).

The problem is local j is not updated immediately, it will be updated in a micro task due to the 2 way binding.

local get message() is rendered twice. First time, by local i change in a micro task, then by local j change in another micro task.

Using @getterThrottle() here will cache wrong value "i:2 j:1", the second update "i:2 j:2" is ignored by the cache.

app.js

import {EventAggregator} from 'aurelia-event-aggregator';
import {inject} from 'aurelia-framework';

@inject(EventAggregator)
export class App {
  i = 1;
  j = 1;

  constructor(ea) {
    this.ea = ea;
    this.ea.subscribe('ttt', () => {
      this.j += 1;
    })
  }
}

app.html

<template>
  <require from="./test"></require>
  <test i.bind="i" j.bind="j"></test>
</template>

test.js

import {EventAggregator} from 'aurelia-event-aggregator';
import {inject, bindable, bindingMode, computedFrom} from 'aurelia-framework';
import {getterThrottle} from 'aurelia-getter-throttle';

@inject(EventAggregator)
export class Test {
  @bindable({defaultBindingMode: bindingMode.twoWay}) i;
  @bindable({defaultBindingMode: bindingMode.twoWay}) j;

  constructor(ea) {
    this.ea = ea;
  }

  update() {
    this.i += 1;
    this.ea.publish('ttt');
  }

  // @getterThrottle()
  @computedFrom('i', 'j')
  get message() {
    const m = `i:${this.i} j:${this.j}`;
    console.log('get message: ' + m)
    return m;
  }
}

test.html

<template>
  <button click.trigger="update()">Update</button>
  <p>${message}</p>
</template>
@3cp
Copy link
Member Author

3cp commented May 25, 2018

By the time of first getter call, the 2 micro tasks were already created. I could not find a way to inject another micro task (to clear cache) between the 2.

@3cp
Copy link
Member Author

3cp commented May 25, 2018

@bigopon any idea to work around?

@bigopon
Copy link

bigopon commented May 25, 2018

Aurelia micro task queue is based on std browser micro task, probably code for micro task queue can be extracted to create a parallel queue that will execute correctly, as they all resolves to underlying browser queue.

@3cp 3cp changed the title Rendering could happen multiple times (in multiple micro tasks), getterThrottle could cache wrong value ~~Rendering~~ could happen multiple times (in multiple micro tasks), getterThrottle could cache wrong value May 25, 2018
@3cp 3cp changed the title ~~Rendering~~ could happen multiple times (in multiple micro tasks), getterThrottle could cache wrong value Rendering (actually not rendering, just task) could happen multiple times (in multiple micro tasks), getterThrottle could cache wrong value May 25, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants