簡體   English   中英

控制余燼承諾解決的順序?

[英]Control the order of ember promise resolution?

我一直在使用本教程2.9.1,節點6.9.1,chrome 53.0.2785.143和OS / X 10.11.6。

當我創建此處描述的組件時: https : //guides.emberjs.com/v2.8.0/tutorial/autocomplete-component/

我最終遇到了比賽狀況。 如果我將字符p輸入到輸入中並非常快速地按退格鍵,則最終將得到由字符p過濾但文本字段中沒有輸入的模型。

一些控制台日志記錄表明發生了這種情況,因為第二個promise(由於輸入為空,將返回所有模型,因為它首先解析),而第一個promise(返回過濾的模型)則是第二個解析。

有什么可以做的嗎?

出於並發目的,有一個名為: ember-concurrency的插件。 您可以將其用於所有異步操作。

ember-power-select也使用此插件。 它是一個功能強大的自動完成選擇組件。 我可以建議您使用它。

編輯2016-10-25:這是使用ember-concurrency更新的代碼,該代碼解決了競爭條件(現在具有正確的屬性名稱):

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();
    }
  }
});

除了ykaragol答案 ,這是我使用ember-concurrency更新的代碼,該代碼解決了競爭情況:

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();
    }
  }
});

只是想出了一個解決方案:存儲對組件的承諾,並在解決它時檢查它是否未被取代,如果沒有,則僅更改狀態。 有沒有更好/更慣用的方式來做到這一點?

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);
        }
      });
    }
  }
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM