Рефакторинг - проверка выполнения обещания
Эта функция получает список пользовательских файлов, предоставляемых внешним API. Как только данные были получены, они сохраняются, поэтому при следующем вызове они возвращают те же данные, которые были сохранены ранее. Этот код находится на уровне контроллера.
var userFiles = {};
function getUserFiles(user) {
var dfd = $q.defer();
// Files already have been loaded
if (userFiles[user.id]) {
dfd.resolve(userFiles[user.id]);
} else {
// Get files for the first time
Users.getFiles(user).then(function(files) {
userFiles[user.id] = files;
dfd.resolve(userFiles[user.id]);
});
}
return dfd.promise;
}
Как бы вы реорганизовали этот код, чтобы он вызывал dfd.resolve только один раз?
2 ответа
РЕДАКТИРОВАТЬ № 2
У меня есть еще лучший фрагмент для вас:
function getUserFiles(user) {
return userFiles[user.id] || (userFiles[user.id] = Users.getFiles(user));
}
Это устанавливает userFiles[user.id]
быть обещанием, возвращенным Users.getFiles(user)
и возвращает его. Если userFiles[user.id]
уже был установлен (т.е. это правда-у), то он просто возвращает ранее разрешенное обещание.
Недостаток использования этого супер-короткого фрагмента в том, что вы не выполняете никакой проверки на сбой - и можете закончить кэшированием ошибочного запроса - но опять же, вы не выполняли никакой проверки на ошибки в другом коде.
РЕДАКТИРОВАТЬ
Согласно документам, вы можете позвонить $q.resolve()
непосредственно без необходимости создания промежуточного объекта с отложенным $q.defer().resolve()
Незначительный рефакторинг, следующий код избавляет вас от создания отложенного, когда вам не нужно. Вам нужно только создать новую отложенную, если файлы уже были загружены. В противном случае вы можете просто перезвонить Users.getFiles()
, как это:
function getUserFiles(user) {
// Files already have been loaded
if (userFiles[user.id]) {
// See Edit Note
// return $q.defer().resolve(userFiles[user.id]);
return $q.resolve(userFiles[user.id]);
}
// Get files for the first time
return Users.getFiles(user)
.then(function(files) {
//Cache them
return (userFiles[user.id] = files);
});
}
var userFiles = {};
function getUserFiles(user) {
var dfd = $q.defer();
if (!userFiles[user.id]) {
// Get files for the first time
Users.getFiles(user).then(function(files) {
userFiles[user.id] = files;
});
dfd.resolve(userFiles[user.id]);
}
return dfd.promise;
}