#javascript
#javascript
Вопрос:
Я пытаюсь создать простой Api-сервис, использующий JavaScript. У этой службы есть 3 свойства (загрузка, данные, ошибка), и я хочу динамически изменять значения этих свойств в promise, и я хочу использовать эту службу таким образом ->
const { loading, data, err } = new ApiService().send(request).getResults();
Моя главная цель — динамическая загрузка и данные, поэтому во время вызова Api значение свойства загрузки равно true, а когда вызов Api завершен, значение свойства загрузки равно false, а свойство data заполнено ответом Api. Итак, я хочу использовать этот сервис таким образом ->
const { loading, data, err } = new ApiService().setSync(false).send(q).getResults();
if (loading) {
pElement.text("Loading");
} else {
pElement.text(data.id);
}
Мои служебные коды Api:
function ApiService(header = {}) {
this._loading = false;
this._data = {};
this._header = header;
this._error = "";
this._isAsync = false;
}
ApiService.prototype.setSync = function (isAsync = false) {
this._isAsync = isAsync;
return this;
};
ApiService.prototype.send = function (request) {
const self = this;
if (!this._isAsync) {
this._loading = true;
request
.then(function (data) {
self._loading = false;
self._data = data;
})
.catch(function (e) {
self._error = e;
});
return this;
} else {
return request
.then(function (data) {
self._loading = false;
self._data = data;
return data;
})
.catch(function (e) {
self._error = e;
});
}
};
ApiService.prototype.getResults = function () {
const self = this;
return { loading: self._loading, data: self._data, err: self._error };
};
module.exports = ApiService;
Эта служба работает один раз, и она возвращает значения по умолчанию как обычно, но я хочу динамическое обновление значений. Возможно ли это?
Ответ №1:
Короткий ответ: Нет. После оператора return вы не можете обновить значения, которые вы имеете в виду.
Такие фреймворки, как React.js у них есть подобный синтаксис в их API Hooks, но у них также есть компоненты, которые выполняются снова каждый раз при изменении состояния, что приводит к переоценке переменных.
В ванильной среде JS проще всего вернуть обещание, дождаться его завершения, а затем продолжить. Я думаю, что использование async / await
— это самое близкое к тому, чтобы ваш код вел себя так, как вам хотелось бы.
Приведенный ниже фрагмент демонстрирует, как это будет выглядеть и выполняться. Возвращаемое loading
значение всегда будет false
таким, каким вы получите результат только после завершения загрузки, поэтому его можно опустить.
function ApiService(header = {}) {
this._loading = false;
this._data = {};
this._header = header;
this._error = "";
this._isAsync = false;
}
ApiService.prototype.send = async function(request) {
this._loading = true;
this._data = {};
this._error = "";
try {
const data = await request();
this._data = data;
} catch(error) {
this._error = error;
} finally {
this._loading = false;
return {
data: this._data,
error: this._error,
};
}
}
(async () => {
pElement.text("Loading");
const { data, err } = await new ApiService().send(request);
if (!err) {
pElement.text(data.id);
}
})();
Комментарии:
1. Спасибо за ваш ответ. Я знаю, как это сделать в контексте React, но я хочу сделать это в ванильном JavaScript, но, насколько я понимаю, мне нужно создать оболочку для повторного отображения функции. Поэтому я отказываюсь от этой функции, потому что я не могу поддерживать эту оболочку.