В этой ситуации может оказаться полезным угольный параллелизм.См. пример «Поиск с опережением», измененный для вашего примера:
const DEBOUNCE_MS = 250;
export default Controller.extend({
flightResults: null;
actions: {
searchFlight(term) {
this.set('flightResults', this.searchRepo(term));
}
},
searchRepo: task(function * (term) {
if (isBlank(term)) { return []; }
// Pause here for DEBOUNCE_MS milliseconds. Because this
// task is `restartable`, if the user starts typing again,
// the current search will be canceled at this point and
// start over from the beginning. This is the
// ember-concurrency way of debouncing a task.
yield timeout(DEBOUNCE_MS);
let url = `https://test.api.amadeus.com/v1/shopping/flight-offers?origin=PAR&destination=LON&departureDate=2018-09-25&returnDate=2018-09-28&adults=1&travelClass=BUSINESS&nonStop=true&max=2`;
// We yield an AJAX request and wait for it to complete. If the task
// is restarted before this request completes, the XHR request
// is aborted (open the inspector and see for yourself :)
let json = yield this.get('getJSON').perform(url);
return json;
}).restartable(),
getJSON: task(function * (url) {
let xhr;
try {
xhr = $.getJSON(url);
let result = yield xhr.promise();
return result;
// NOTE: could also write this as
// return yield xhr;
//
// either way, the important thing is to yield before returning
// so that the `finally` block doesn't run until after the
// promise resolves (or the task is canceled).
} finally {
xhr.abort();
}
}),
});