В компоненте Vue у меня есть два асинхронных вызова данных из разных источников (один вызов HTTP, один вызов кэша браузера), и я хочу, чтобы загрузчик вращался, пока оба не будут завершены. Когда оба завершены, компонент загружается, так сказать.
...
data() {
return {
loading: true
}
},
mounted: function() {
this.getData(); // HTTP Async API
this.getOtherData(); // IndexedDB Async API
},
...
Я пытаюсь выяснить, как правильно установить для загрузки значение false, когда оба возвращают данные. Мой текущий подход к использованию флагов выглядит грязным, но я не уверен, что это лучший подход.
...
data() {
return {
loading: true,
flagA: false,
flagB: false
}
},
mounted: function() {
this.getData(); // HTTP Async API
this.getOtherData(); // IndexedDB Async API
},
methods: {
getData() {
...
//Once done
this.flagA = true
if (this.flagA == true && this.flagB == true) this.loading = false
},
getOtherData() {
...
//Once done
this.flagB = true
if (this.flagA == true && this.flagB == true) this.loading = false
}
...
Есть ли лучший подход?
РЕДАКТИРОВАТЬ, чтобы показать не HTTP-функцию:
getOtherData() {
var request = indexedDB.open("Database", 1);
request.onerror = event => {
//IndexedDB is not supported. Resort to fallback option and continue regular program flow
};
request.onsuccess = event => {
this.db = event.target.result;
var transaction = this.db.transaction(["project"], "readwrite");
var projectStore = transaction.objectStore("project");
var projectReq = projectStore.get(1);
projectReq.onsuccess = () => {
this.flagB = true;
};
projectReq.onerror = () => {
//error
};
};
Пока обе функции возвращают промис, используйте хук жизненного цикла async
и Promise.all
. Он работает независимо от того, исходит ли это обещание из http-запроса или просто возвращается из метода:
async mounted() {
const p1 = axios.get('getData'); // not awaited, just returning promise
const p2 = this.getOtherData(); // not awaited, just returning promise
// awaiting both, responses will be in `response1` and `response2`
const [ response1, response2 ] = await Promise.all([p1, p2]);
this.loading = false;
}
Убедитесь, что все функции возвращают обещание, если вы не используете обещание http напрямую:
getData() {
...
return request;
},
getOtherData() {
...
return request;
}
Эта другая функция должна возвращать обещание, и тогда она может работать так же. Попробуйте return request
в конце getOtherData
. Я отредактировал, чтобы показать код ловушки для этого
Ваше решение не работает pastebin.com/wYmgU4HF
Вы нигде не установили переменные, которые вы регистрируете. И вы не возвращаете обещание ни в одной из функций. Это должно быть return this.$axios...
в getData
и return request
в конце getOtherData
. Внимательно изучите ответ
Тут должно быть все понятно: jsfiddle.net/sh0ber/wju39z7b
Смотрите мою правку. Я знаю этот подход для axios, но как я могу сделать это для функции axios и non-anxios?