Javascript 控制余烬承诺决议的顺序?

Javascript 控制余烬承诺决议的顺序?,javascript,ember.js,Javascript,Ember.js,我一直在遵循教程,使用了ember 2.9.1、node 6.9.1、chrome 53.0.2785.143和OS/X 10.11.6 创建此处描述的组件时: 我以比赛状态结束。如果我在输入中输入字符p并快速点击backspace,我最终得到的模型是由字符p过滤的,但在文本字段中没有输入 一些控制台日志表明这是因为第二个承诺(返回所有模型,因为输入为空)是先解析的,而第一个承诺(返回过滤后的模型)是第二个解析的 有什么办法可以解决这个问题吗?刚刚提出了一个解决方案:针对组件存储承诺,并在解决

我一直在遵循教程,使用了ember 2.9.1、node 6.9.1、chrome 53.0.2785.143和OS/X 10.11.6

创建此处描述的组件时:

我以比赛状态结束。如果我在输入中输入字符p并快速点击backspace,我最终得到的模型是由字符p过滤的,但在文本字段中没有输入

一些控制台日志表明这是因为第二个承诺(返回所有模型,因为输入为空)是先解析的,而第一个承诺(返回过滤后的模型)是第二个解析的


有什么办法可以解决这个问题吗?

刚刚提出了一个解决方案:针对组件存储承诺,并在解决它时检查它是否被取代,只有在没有被取代时才更改状态。有没有更好/更惯用的方法

import Ember from 'ember';

export default Ember.Component.extend({
  classNames: ['list-filter'],
  value: '',
  currentPromise: null,

  init() {
    this._super(...arguments);
    this.get('filter')('').then((results) => this.set('results', results));
  },

  actions: {
    handleFilterEntry() {
      const filterInputValue = this.get('value');
      const filterAction = this.get('filter');

      const thePromise = filterAction(filterInputValue);
      this.set('currentPromise', thePromise);

      thePromise.then((filterResults) => {
        if (thePromise == this.get('currentPromise')) {
          this.set('results', filterResults);
        }
      });
    }
  }
});

出于并发目的,有一个名为:。您可以将其用于所有异步操作

也使用这个插件。它是一个功能强大的自动完成选择组件。我可以建议你使用它

编辑2016-10-25:以下是使用ember并发解决争用条件的更新代码(现在具有正确的属性名称):

下面是我的更新代码,用于解决竞争条件:

import Ember from 'ember';
import { task } from 'ember-concurrency';

export default Ember.Component.extend({
  classNames: ['list-filter'],
  value: '',

  init() {
    this._super(...arguments);
    this.get('filter')('').then((results) => this.set('results', results));
  },

  handleFilterEntryTask: task(function * () {
    const filterInputValue = this.get('value');
    const filterAction = this.get('filter');

    const filterResults = yield filterAction(filterInputValue);
    this.set('results', filterResults);

  }).keepLatest(),

  actions: {
    handleFilterEntry() {
      this.get('handleFilterEntryTask').perform();
    }
  }
});

我将接受这一点,但我也想发布生成的源代码!我将把它放在另一个答案中,但请随意复制到您的答案中。请注意,您只需执行
handlefiltertrytask
即可删除
handlefiltertrytask
操作的冗余,只需使用
perform handlefiltertrytask
即可使用
操作“handlefiltertrytask”
。另外,在最近的余烬中(我认为>=2.4?),您可以只使用
action handleFilterEntryTask
,它就可以工作了。
import Ember from 'ember';
import { task } from 'ember-concurrency';

export default Ember.Component.extend({
  classNames: ['list-filter'],
  value: '',

  init() {
    this._super(...arguments);
    this.get('filter')('').then((results) => this.set('results', results));
  },

  handleFilterEntryTask: task(function * () {
    const filterInputValue = this.get('value');
    const filterAction = this.get('filter');

    const filterResults = yield filterAction(filterInputValue);
    this.set('results', filterResults);

  }).keepLatest(),

  actions: {
    handleFilterEntry() {
      this.get('handleFilterEntryTask').perform();
    }
  }
});