#javascript #jquery #backbone.js
#javascript #jquery #backbone.js
Вопрос:
Итак, я создал объект api, который может быть включен в любой файл JavaScript через require.js . В объекте api у меня есть вызовы для создания базовых моделей / коллекций, подобных показанной ниже:
getDatapoints: function(attributes, callback) {
require(['models/datapoint'], function(Datapoint){
var datapoint = new Datapoint.DatapointCollection(attributes);
datapoint.fetch({success: function(data){
return callback(data.toJSON());
}});
});
}
Я хочу иметь возможность запускать несколько вызовов и запускать функцию обратного вызова после завершения ВСЕХ вызовов. Похоже, функция jQuery $.when делает то, что я хочу, но я не уверен, как заставить ее работать с чем-либо, кроме вызовов $.ajax.
Я смотрю в нужном месте? Должен ли я смотреть на что-то вроде q.js?
Комментарии:
1. я не понимаю, как помогут обещания. разве они не предназначены для выполнения большого количества задач в одном процессе? кажется, это больше похоже на выполнение одной вещи для многих процессов. а именно, не будут ли обещания jQuery вызывать каскад сетевой активности при одновременной загрузке многих?
2. @dandavis не обязательно.
$.when.apply($, [fetch1(), fetch2(), fetch3()]).done(dostuff)
будет получать 1, 2 и 3 одновременно, а затем, когда все три будут завершены,dostuff
. Для этого просто потребуется заставить getDatapoints возвращать обещание, например, с обоими текущими ответами.3. @KevinB правильно, мой ответ точно показывает, как это сделать.
4. @KevinB: хорошая информация и идея об использовании apply().
Ответ №1:
Расширяя ответ @mattacular:
API = {
getDatapoints: function (attributes){
var dfd = $.Deferred();
require(['models/datapoint'], function(Datapoint){
var dataPoints = new Datapoint.DatapointCollection(attributes);
dataPoints.fetch().then(function (points){
dfd.resolve(points.toJSON());
}, function (error){
dfd.reject(error);
});
});
return dfd.promise();
},
getAllDatapoints: function (arrayOfAttributes){
var arrayOfPromises = arrayOfAttributes.map(this.getDatapoints);
return $.when.apply($, arrayOfPromises);
}
}
И где вы на самом деле вызываете getAllDatapoints
метод:
var allDatapointAttributes = [{...}, {...}, {...}];
API.getAllDatapoints(allDatapointAttributes).done(function(){
console.log.apply(console, arguments);
// should output an array of arrays containing dataPoint
// objects when all the requests have completed successfully.
});
Ответ №2:
Вы можете сделать это с помощью отложенного объекта jQuery. Вот краткий пример:
getDatapoints: function (attributes, callback() {
var dataPoints = $.Deferred();
// perform async calls here
// when "done," call dataPoints.resolve() or dataPoints.reject() accordingly
return dataPoints.promise();
}
редактировать: удален устаревший учебник
Комментарии:
1. Статья, на которую вы ссылались, довольно старая (почти три года). В нем упоминается
$.Deferred#pipe()
то, что, по моему мнению, либо устарело, либо вообще исчезло. Вместо этого вы должны использовать$.Deferred#then()
.2. Да, извините, это старая закладка, которую я вытащил. Он устарел. Если у вас есть лучшая ссылка, я отредактирую свой ответ, но кто-то другой уже разработал другой ответ, поэтому, вероятно, в этом нет необходимости.