Когда вы представляете выходной формат JSON для разработчиков, имеет смысл также дать возможность передачи параметра «функция обратного вызова». При этом возникает возможность использования вашего выходного формата с помощью простого использования тэга script, без использования какого-либо Ajax. Предположим, к примеру, что вы предоставляете API, чтобы вернуть имена участников группы Битлз, предоставляя конечную точку и параметр для задания выходного формата:
example.com/API/getBeatles?output=jsonВозвращаемые данные представлены в форме:
{
"members":
[
'Paul':{ ... more info ... },
'Ringo':{ ... more info ... },
'John':{ ... more info ... },
'George':{ ... more info ... }
]
}
* This source code was highlighted with Source Code Highlighter.Это я не смогу использовать в JavaScript без финтов. Мне нужно будет выполнить eval (или более безопасный JSON.parse) над полученными данными, и к тому же обычным Ajax я не смогу получить доступ к данным за пределами своего домена. Чтобы сделать доступ к данным JSON более простым, Вы можете предоставить параметр обратного вызова.
example.com/API/getBeatles?output=json&callback=eleanorRigbyПри наличии этого параметра результаты оборачиваются в вызов функции, что означает, что результат будет уже вычислен, и пользователь определил функцию обратного вызова для чтения данной информации.
eleanorRigby({
"members":
[
'Paul':{ ... more info ... },
'Ringo':{ ... more info ... },
'John':{ ... more info ... },
'George':{ ... more info ... }
]
});
* This source code was highlighted with Source Code Highlighter.Если я определю функцию наподобие
eleanorRigby(o){}, параметр o будет обьектом с полученными данными, и я смогу использовать их немедленно.<script>
function eleanorRigby(o){
alert(o['John']); // will alert the information about John
}
</script>
<script src="http://example.com/API/getBeatles?output=json&callback=eleanorRigby"></script>
* This source code was highlighted with Source Code Highlighter.Но в таком случае проблема возникает, что в случае, если функция
eleanorRigby не определена, будет выброшено исключение.Bing API является первым экземпляром сервиса, который я видел, который обрамляет свой вывод в виде:
if(typeof eleanorRigby == 'function') eleanorRigby(
{
"SearchResponse":
{
"Version":"2.2",
"Query":
{
"SearchTerms":"a hard day's night"
},
"Translation":
{
"Results":
[
{"TranslatedTerm":"einem harten Tag-Nacht "}
]
}
}
} /* pageview_candidate */);
* This source code was highlighted with Source Code Highlighter.Я не в курсе, что означает комментарий /* pageview_candidate */, и мне не нравится отсутствие блока {} после if, но сама идея мне нравится.
Проблема в этом коде только одна — ошибки такого рода теперь молча пропускаются, что может усложнить процесс отладки. Вероятно, более красиво было бы в случае ошибки писать сообщение в консоль, если функция обратного вызова не определена.
if(typeof callback === 'function') {
callback(... data ... );
} else {
if (typeof console!=='undefined' &&
typeof console.log !== 'undefined'){
console.log('Error: Callback method not defined');
}
}
* This source code was highlighted with Source Code Highlighter.В целом весьма интересный подход!
От переводчика: Кстати, получение данных через тэг script часто также более производительно по сравнению с eval и иногда даже по сравнению с нативным JSON.parse. По ссылке, правда, сравнения именно с JSONP нет.

