Что ж, вы могли бы вместо этого использовать Promises для цепочки и использовать данные, которые вы передаете, чтобы что-то делать с этими данными, когда вы проходите через цепочки.
Итак, если вам нужен пример реализации с использованием обещаний,и обработки передаваемых данных, вы можете посмотреть на следующий код, он:
- получает случайное изображение
- передает URL-адрес изображения в результате
- это изображениеURL-адрес затем используется для предварительной загрузки изображения и возвращает элемент изображения
- , затем отображается элемент изображения
- , напечатан оператор console.log
function retrieveData() {
return $.when( $.getJSON('https://dog.ceo/api/breeds/image/random')
.then( data => data.message ) );
}
function retrieveImage( source ) {
return new Promise( (resolve, reject) => {
const image = new Image();
image.addEventListener( 'load', function() {
resolve( image );
} );
image.src = source;
} );
}
function displayImage( image ) {
document.getElementById('image-container').appendChild( image );
return Promise.resolve( true );
}
retrieveData()
.then( retrieveImage )
.then( displayImage )
.then( () => console.log('all done') )
.catch( err => console.error( err ) );
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="image-container"></div>
Поскольку обещание будет ожидать завершения (или отказа) возвращенных обещаний, все это идет друг за другом, поэтому оператор журнала не будет напечатан доэлемент был отображен.
Если 1 шаг не пройден, он перейдет к следующему catch
в цепочке.В моем примере есть только 1 перехват (и я не обрабатываю ошибки из $.getJSON
), поэтому, если что-то пойдет не так, это должно вывести ошибку в консоли.
Конечно, вы можете использовать оператор $.when
, предоставленный jQuery, чтобы сделать почти то же самое, так как он возвращает Promise
Таким образом, примененный к вашему коду, вы должны return
$.getJSON
из вашей функции синтаксического анализа, а затем на основе этой цепочки
var myJSON;
function _parseJSON() {
// return here, no need returning exactly what you would expect anyhow
return $.getJSON(settings.json_src);
}
// because you returned, you can chain everything nicely together
$.when( _parseJSON() )
// don't forget the argument here
.then(function( data ) { myJSON = data; })
// and these will only run after the myJSON got set
.then( _cacheOptions )
.then( _cacheDom )
.then( _events )
.then( _render );
Хотя я бы действительно предложил не работать с глобальными переменными.Если вы добавите аргументы к функциям, которые вы вызываете, эти функции станут независимыми от любых магических переменных и вместо этого могут стоять самостоятельно
Обратите внимание, что если какая-либо из ваших цепочек возвращает отложенный объект, она будет ждатьэтот отложенный объект должен быть завершен.
Обратите внимание, что мы сами не вызываем методы в цепочке, мы просто передаем ссылку на функцию, чтобы ее можно было вызывать последовательно (например: _events
vs _events()
)