1 (изменено: powercat, 2018-01-23 02:01:13)

Тема: JavaScript: var, object ( Отображение информации JSON без query )

Здравствуйте. Есть сайт с которого нужно вытянуть UNIX время. http://time.jsontest.com/
Проблема в том, что нужно объявить переменную вне функций с значением текущего UNIX времени, но у меня выводит: undefined или [ objects Object ]. Код ниже, помогите разобраться в чем проблема. Спасибо.

var getJSON = function(url, callback) {

    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.responseType = 'json';
    
    xhr.onload = function() {
    
        var status = xhr.status;
        
        if (status == 200) {
            callback(null, xhr.response);
        } else {
            callback(status);
        }
    };
    
    xhr.send();
};

var getcurdate = getJSON('http://time.jsontest.com',  function(err, data) {
    
    if (err != null) {
        console.error(err);
    } else {
        
        var curdate = `${data.milliseconds_since_epoch}`
    }
return getcurdate;
});
alert (getcurdate);

2 (изменено: svoboden, 2018-01-28 03:52:51)

Re: JavaScript: var, object ( Отображение информации JSON без query )

Так у меня со второго раза определяет:

var getJSON = function(url, callback) {

    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.responseType = 'json';
    
    xhr.onload = function() {
    
        var status = xhr.status;
        
        if (status == 200) {
            callback(null, xhr.response);
        } else {
            callback(status);
        }
    };
    
    xhr.send();
};
getcurdate = getJSON('http://time.jsontest.com', 
 function(err, data) {
    if (err != null) {
        console.error(err);
    } else {
       curdate = `${data.milliseconds_since_epoch}`
    }
return getcurdate
});
alert(curdate);

3

Re: JavaScript: var, object ( Отображение информации JSON без query )

Господа, возможно я что-то не уловил, но ведь можно проще ?


<!doctype html>
<html lang="ru">
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
		<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
		<script type="text/javascript">
			$(function(){
				$.getJSON("http://time.jsontest.com/", function(data) {
					alert(data.milliseconds_since_epoch);
				})
				.fail(function() {
					alert("request error");
				})
			})
		</script>
	</head>
</html>
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

4 (изменено: svoboden, 2018-01-31 06:56:39)

Re: JavaScript: var, object ( Отображение информации JSON без query )

Проще та проще, но ведь нужно объявить переменную вне функции.

5

Re: JavaScript: var, object ( Отображение информации JSON без query )

svoboden, понял. Действительно, не обратил внимания. Хорошо, тогда такой вариант:


<!doctype html>
<html lang="ru">
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
		<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
		<script type="text/javascript">
		
			var milliseconds_since_epoch;
			
			$.ajax({
				url:		"http://time.jsontest.com/",
				dataType:	"json",
				async:		false,
				success:	function(data){
					milliseconds_since_epoch = data.milliseconds_since_epoch;
				},
				error: function(jqXHR, textStatus, errorThrown){
					alert('Time request failed ! ' + textStatus + ' ' + errorThrown);
				}
			});
			
			alert(milliseconds_since_epoch);
			
		</script>
	</head>
</html>
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

6 (изменено: svoboden, 2018-01-31 11:57:17)

Re: JavaScript: var, object ( Отображение информации JSON без query )

Xameleon, и, по правде говоря, еще тс просил разобраться с кодом, который он привел. . Но, может, и этот пойдет.
Вообщем примерно так:

var getJSON = function(url, callback) {

    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.responseType = 'json';
    xhr.onload = function() {
        var status = xhr.status;
        if (status == 200) {
            callback(null, xhr.response);
        } else {
            callback(status);
        }
    };
    xhr.send();
};
getcurdate = getJSON('http://time.jsontest.com',
 function(err, data) {
    if (err != null) {
        console.error(err);
    } else {
   curdate = `${data.milliseconds_since_epoch}`;
    }
});

setTimeout(function () {
alert(curdate);
}, 1000);

7

Re: JavaScript: var, object ( Отображение информации JSON без query )

svoboden, я умышленно минимизировал код тс, так как п.м.с.м он:
1) не универсален для разных браузеров
2) громоздок
3) не учитывает обработку ошибок при разборе данных json
4) Выдаёт ошибку в строке:

curdate = `${data.milliseconds_since_epoch}`;

С Вашим кодом тоже не могу полностью согласиться:
1)


setTimeout(function () {
alert(curdate);
}, 1000);

Получается не надёжная проверка. Ответ может вернуться раньше чем сработает таймаут и тогда скрипт будет в пустую ждать дольше. Либо ответ может вернуться позже чем через секунду и тогда опять же скрипт сработает неправильно. Поэтому я предпочёл использовать документированные возможности jQuery для синхронного запроса.

2) Проблему с ошибкой на строке curdate = `${data.milliseconds_since_epoch}`; так и осталась.

Сейчас заметил, автор уточнил, что нужно обойтись без "query". Т.е видимо без jQuery.

Раз так, то можно, наверное сократить всё до такого варианта, но тут уже надо понимать на какие браузеры ориентирована задача:


<!doctype html>
<html lang="ru">
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
		<script type="text/javascript">
			with(new XMLHttpRequest()){
				open('GET', 'http://time.jsontest.com', false);
				responseType = 'json';
				send();
				alert(JSON.parse(responseText).milliseconds_since_epoch)
			};
		</script>
	</head>
</html>
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

8 (изменено: svoboden, 2018-01-31 23:08:44)

Re: JavaScript: var, object ( Отображение информации JSON без query )

Там я имел в виду, что через консоль нужно сначала выполнить функцию, а потом выполнить следующий код.

9

Re: JavaScript: var, object ( Отображение информации JSON без query )

svoboden, к сожалению, не совсем Вас понял. Если можно, поясните, пожалуйста, подробнее.
1) В том коде я вижу 3 функции. Одна "getJSON", вторая безымянная в setTimeout, третья вложена в вызов getJSON. Какую из них вы предлагаете предварительно выполнить в консоли и для каких целей ?
2) Тс про консоль вроде ничего не говорил ? Из чего я сделал вывод, что ему нужно готовое решение для страницы ? Ошибаюсь ?

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

10 (изменено: svoboden, 2018-02-02 03:26:57)

Re: JavaScript: var, object ( Отображение информации JSON без query )

1) Тс нужно вытянуть UNIX время из страницы, а про готовое решение для страницы, я что-то не вижу, где бы он такое писал.

Xameleon пишет:

Какую из них вы предлагаете предварительно выполнить в консоли и для каких целей ?

Я не знаю, для каких целей тс нужно выполнить код в консоли.
2) Насчет запуска из консоли, я сделал такой вывод, исходя из этой строчки: "console.error(err);" в примере кода.
3) И с чего вы взяли, что выше функция может долго ждать ответ?
Я, например, тестировал alert внутри 3-ой функции после else, и у меня всегда работало.

11

Re: JavaScript: var, object ( Отображение информации JSON без query )

svoboden,

1)

Тс нужно вытянуть UNIX время из страницы, а про готовое решение для страницы, я что-то не вижу, где бы он такое писал.
....
Я не знаю, для каких целей тс нужно выполнить код в консоли.

Хорошо, про готовое решение соглашусь - об этом не было упомянуто, но не было и упомянуто о том, чтобы выполнять код в консоли. Вызовы типа:

console.error(err)

на мой взгляд, не говорят о том, что весь код будет исполняться в консоли, а лишь о том, что тс пытался отлаживать код выводя сообщения в консоль.

Второй момент. Выполнять функцию в консоли предложили Вы:

Там я имел в виду, что через консоль нужно сначала выполнить функцию, а потом выполнить следующий код.

Так как функций несколько, о чём я уже писал, я решил уточнить какую именно Вы предлагаете выполнить в консоли и для каких целей, так как мне не совсем была понятна цель этого действия и до сих пор не ясна.

2)

Насчет запуска из консоли, я сделал такой вывод, исходя из этой строчки: "console.error(err);" в примере кода.

Об это я уже написал в первом пункте.

3)

И с чего вы взяли, что выше функция может долго ждать ответ ?

С радостью поясню. Так как запрос уходит через web, то время ответа сервера может быть разным. Для примера я решил внести небольшие изменения, в приведённый Вами код.
а) Заменил url, на который происходит обращение на http://my-server.ml/test/. Серверный скрипт по этому адресу принимает параметр delay (задержка) для выполнения задержки на n миллисекунд. Т.е симулирует задержку, которая может произойти в результате отдачи объёмного контента, либо в результате нестабильного интернет соединения, либо в виду прочих причин.
б) в событии onload добавил

alert('request complete');

, чтобы мы могли узнать когда пришёл ответ от сервера.
в) Исправил место, где в коде происходила ошибка.


curdate = `${data.milliseconds_since_epoch}`;

заменил на


curdate = JSON.parse(data).milliseconds_since_epoch;

Это не очень хорошее решение, так как опять же не универсальное для браузеров, но для теста нам вполне подойдёт.

Итак код:


<!doctype html>
<html lang="ru">
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
		<script type="text/javascript">
			var getJSON = function(url, callback) {

				var xhr = new XMLHttpRequest();
				xhr.open('GET', url, true);
				xhr.responseType = 'json';
				xhr.onload = function() {
					alert('request complete');
					var status = xhr.status;
					if (status == 200) {
						callback(null, xhr.response);
					} else {
						callback(status);
					}
				};
				xhr.send();
			};
			getcurdate = getJSON('http://my-server.ml/test/',
			 function(err, data) {
				if (err != null) {
					console.error(err);
				} else {
					curdate = JSON.parse(data).milliseconds_since_epoch;
				}
			});

			setTimeout(function () {
				alert(curdate);
			}, 1000);
			
		</script>
	</head>
</html>

Можете провести у себя тест:
1) При запросе без указания задержки сначала получаем сообщение "request complete" и только потом, по истечении таймаута, уже сообщение с данными.

2) Если же мы заменяем url на http://my-server.ml/test/?delay=3000, то в консоли происходит ошибка:

"curdate" не определено

так как сначала срабатывает таймаут, выполняя функцию с выводом значения переменной, не дождавшись ответа сервера и уже потом появляется сообщение о завершении выполнения запроса.

Именно по этой причине, я указал Вам на ненадёжность использования таймаута в коде.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

12 (изменено: powercat, 2018-02-03 05:51:03)

Re: JavaScript: var, object ( Отображение информации JSON без query )

Код нужен для расширения. Браузер только Google Chrome. Нужно вытянуть UNIX время и объявить переменну вне функции, чтобы была возможность использовать переменную в других местах.

13

Re: JavaScript: var, object ( Отображение информации JSON без query )

powercat, прекрасно. Тогда поясните, пожалуйста 3 момента:
1) предложенные решения кода Вас устроили или что-то ещё требуется ?
2) Если не секрет, почему у Вас в заголовке написано, "Отображение информации JSON без query", а в коде строка, хоть и с ошибками, но явно намекающая на желание использовать jQuery, судя по символу "$":


curdate = `${data.milliseconds_since_epoch}`

Или имеется в виду нечто иное ?
3) Судя по коду, вы хотите создать функцию для запроса данных с callback-ом. Если так, то опять же зачем изобретать "велосипед", если в jQuery это всё уже прекрасно решено. Причём решено кроссбраузерно, гибко, с миниморумом кода и в самых разных вариациях (события, промисы, коллбэки) ?

P.S Возможно я чего-то не учитываю ? При написании расширения для хрома есть ограничения ?

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

14 (изменено: svoboden, 2018-02-17 17:45:35)

Re: JavaScript: var, object ( Отображение информации JSON без query )

Xameleon пишет:

так как сначала срабатывает таймаут, выполняя функцию с выводом значения переменной, не дождавшись ответа сервера и уже потом появляется сообщение о завершении выполнения запроса.

Я не совсем понимаю ваш пример, но таймаут не дожидается ответа сервера, он ждет выполнения функции:

alert(1);
setTimeout(alert, 3000, 2);
alert(3);

Или более наглядно:

function pause(delay) {
  var startTime = Date.now();

  while (Date.now() - startTime < delay);
}

var getJSON = function(url, callback) {

    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.responseType = 'json';
    xhr.onload = function() {
        var status = xhr.status;
        if (status == 200) {
            callback(null, xhr.response);
        } else {
            callback(status);
        }
    };
    xhr.send();
};
getcurdate = getJSON('http://time.jsontest.com',
 function(err, data) {
    if (err != null) {
        console.error(err);
    } else {
   curdate = `${data.milliseconds_since_epoch}`;
pause(3000);
    }
});

setTimeout(function () {
alert(curdate);
}, 1000);

15

Re: JavaScript: var, object ( Отображение информации JSON без query )

svoboden,

Я не совсем понимаю ваш пример, но таймаут не дожидается ответа сервера, он ждет выполнения функции:

Печально. Как я уже написал выше, предложенный Вами таймаут, может вызывать ошибку, в случае если событие onload сработает позже него, либо таймаут может продолжать ожидание не смотря на то что данные уже пришли, если событие произошло ранее. Не хочу повторно расписывать то, что уже писал выше. Пожалуйста, изучите более детально пример из предыдущего сообщения. Я постарался максимально подробно и понятно пояснить чем плох таймаут в этом случае. И прошу, не дублируйте ошибку со строкой:


curdate = `${data.milliseconds_since_epoch}`;

Ведь уже очевидно, что это приводит к неработоспособности кода.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

16 (изменено: svoboden, 2018-02-17 20:54:25)

Re: JavaScript: var, object ( Отображение информации JSON без query )

Да, только что проверял на примере автора вопроса. Действительно, ответ может прийти позже.

17

Re: JavaScript: var, object ( Отображение информации JSON без query )

Xameleon, согласен насчет задержки. Но ваша строка curdate = JSON.parse(data).milliseconds_since_epoch; не работает.

18

Re: JavaScript: var, object ( Отображение информации JSON без query )

svoboden,

curdate = JSON.parse(data).milliseconds_since_epoch; не работает.

А вы в каком браузере проверяете ? )

Я как раз по этой причине, сразу под кодом написал:

Это не очень хорошее решение, так как опять же не универсальное для браузеров, но для теста нам вполне подойдёт.

Для IE11 работает без проблем. Так как в нём JSON объект уже встроен. На сколько мне известно, нативная поддержка JSON присутствует в:

IE8+
Firefox 3.1+
Safari 4.0.3+
Opera 10.5+

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

19 (изменено: svoboden, 2018-02-17 21:00:37)

Re: JavaScript: var, object ( Отображение информации JSON без query )

Google Chrome. А работает такой вариант:
curdate = data.milliseconds_since_epoch или пример автора вопроса.

20

Re: JavaScript: var, object ( Отображение информации JSON без query )

svoboden, благодарю за уточнение. Действительно, не учёл момент, что Google Chrome делает автоматическое преобразование данных в объект. Дабы не было ошибки, достаточно убрать из кода строку:


xhr.responseType = 'json';

При этом автоматического преобразования данных не будет происходить.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !