Самый простой способ возобновить код после асинхронного вызова - воспользоваться функцией обратного вызова. Это будет выглядеть примерно так:
function getRM(callback) { // <--- accepts a callback param
const handleResponse = function (status, response) {
localStorage.setItem('return_matrix', response);
callback(); // <--- calling the callback
})
const http=new XMLHttpRequest();
// ...etc
}
И привык бы что-то вроде этого:
function createTableData() {
if (localStorage.getItem('return_matrix') === null) {
getRM(doWork);
} else {
doWork();
}
}
// I split this out into a helper function because it sometimes needs to be
// called synchronously, sometimes asynchronously, and i didn't want to
// duplicate the code.
function doWork() {
const returnMatrix = JSON.parse(localStorage.getItem('return_matrix');
//... etc
}
Обратные вызовы работают, но могут быть несколько сложными, если вы хотите объединить их в цепочку или устранить ошибки. Еще одна распространенная техника, которая улучшает это, - Обещания. Обещание - это объект, представляющий конечную ценность. Вы можете получить доступ к этому возможному значению, вызвав метод обещания .then и предоставив обратный вызов.
Многие библиотеки для выполнения http-запросов (например, axios , fetch ) возвращают обещание, поэтому вы можете работать с ними, не делая ничего лишнего. В вашем примере, хотя вы вручную делали XHR, и в него не встроены обещания. Но вы все равно можете добавить их, если хотите, что-то вроде этого:
function getRM() {
// creating a promise object
return new Promise((resolve, reject) => {
const handleResponse = function (status, response) {
localStorage.setItem('return_matrix', response);
resolve(); //<--- calling resolve instead of callback
}
const http = new XMLHttpRequest();
// ...etc
});
}
И вы будете использовать это так:
function createTableData() {
if (localStorage.getItem('return_matrix') === null) {
getRM().then(doWork);
} else {
doWork();
}
}
Теперь, когда код использует обещания, еще одно уточнение, которое мы можем сделать, - это использовать async / await, что немного упрощает синтаксис для работы с обещаниями. Эта версия будет выглядеть так:
async function createTableData() {
if (localStorage.getItem('return_matrix') === null) {
await getRM();
}
// I've moved the code back in line, since it's no longer needed in 2 places
const http=new XMLHttpRequest();
//... etc
}
И теперь он снова выглядит почти так же, как и раньше, за исключением того, что теперь getRM возвращает обещание, а createTableData будет ожидать разрешения этого обещания.