[英]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.