Можно ли, как-то, чтобы вызвать функцию асинхронной (например, таймер/АЯКС вызова), в основном общую задачу асинхронной и синхронно ждать, пока не закончится, не имея 100% загрузки процессора и заблокированного браузер?
Нет. Вы не можете «синхронно ждать» результата async в Javascript. Из-за того, что это однопоточный и управляемый событиями дизайн, он просто не сработает.
Поскольку большинство других разговоров/комментариев по этому вопросу носило концептуальный характер, я подумал, что предлагаю ответ о том, как вы практически решите свою конкретную проблему, используя подходящий асинхронный дизайн.
Javascript не предлагает возможность спать, пока заканчивается какая-то длительная деятельность. Таким образом, вы не можете создать свою функцию updateCSS()
, чтобы иметь чисто синхронный интерфейс. Вместо этого вам нужно будет использовать асинхронные инструменты в Javascript для разработки интерфейса, который будет работать как в случае кэширования ресурса, так и при использовании ресурса по сети.
Обычный способ проектирования для этого - создать асинхронный интерфейс, и если ресурс будет кэшироваться, вы все равно будете обслуживать его через асинхронный интерфейс. Затем у вас есть один интерфейс, который может использовать вызывающий, и этот интерфейс всегда работает, будет ли кешированный ресурс или нет. Это требует, чтобы вызывающий абонент использовал асинхронный интерфейс.
Практически, вы можете создать как этот getCachedResource()
:
function getCachedResource(url) {
//...
if (cached) {
// returns a promise who's resolved value is the resource
return Promise.resolve(cached);
} else {
// returns a promise who's resolved value is the resource
return doAjax(...);
}
}
Здесь getCachedResource()
всегда возвращает обещание, будет ли в кэше значение или нет. Таким образом, абонент всегда использует интерфейс обещания, как это:
getCachedResource(...).then(function(result) {
// use the result here
});
Если результат происходит в кэше, то .then()
обработчик будет вызван немедленно (на следующем такте). Если результат будет получен по сети, обработчик .then()
будет вызываться, как только будет доступен результат. Вызывающему не нужно беспокоиться о том, где и как был восстановлен ресурс - у них есть один интерфейс для его получения.
В функции updateCSS()
вы должны будете разработать для использования асинхронного интерфейса в getCachedResource()
. Поскольку ваш текущий дизайн использует синхронный обратный вызов в css.replace()
, вам придется переосмыслить это немного, чтобы соответствовать асинхронному поиску. Вот один из способов, как это сделать.
function updateCSS(url) {
return getCachedResource(url).then(function(css) {
// preflight the replacements we need to do so we know what to fetch
var urls = [];
css.replace(/regexp/gm, function(curUrl) {
urls.push(curUrl);
});
// now load all the resources
return Promise.all(urls.map(getCachedResource)).then(function(resources) {
// now have all the resources, in proper order
var index = 0;
css = css.replace(/regexp/gm, function(curUrl) {
return resources[index++];
});
// final resolved value is the fully loaded css
return css;
})
});
}
Схема здесь, чтобы запустить фиктивный .replace()
, не держать результат, чтобы создать список URL-адресов, которые необходимо загрузить. В зависимости от вашего регулярного выражения это также можно сделать с помощью .match()
или .exec()
. Затем, как только у вас появится список URL-адресов, вы получите все. Когда у вас есть все они, вы можете запустить .replace()
по-настоящему, потому что у вас есть ресурсы, доступные для использования в синхронном обратном вызове .replace()
.
Один не может затем использовать это так:
updateCss(someCSSURL).then(function(css) {
// use the CSS here
}).catch(function(err) {
// process error here
});
Ответ ** нет **. Добро пожаловать в программирование в JavaScript :) – Pointy
нет абсолютно ничего, что может превратиться асинхронно в синхронное. Если вы остановитесь и подумаете об этом, это понятно. 'код будет ... ужасным' - объять асинхронность, и код снова может быть красивым –
Yup. Грустно :) Я никогда не пойму, почему они не реализовали ожидание async op. – Fis