Ваши варианты следующие:
- Попросите сервер вставить идентификатор в ответ. Это самый чистый, но часто вы не можете изменить код сервера.
- Если вы можете гарантировать, что никогда не будет более одного вызова JSONP, вовлекающего вставку идентификатора одновременно, тогда вы можете просто вставить значение идентификатора в глобальную переменную, а когда вызывается обратный вызов, извлечь значение идентификатора из глобальной переменной. , Это просто, но хрупко, потому что если в процессе одновременно присутствует каждый вызов JSONP, включающий ID, они наступают друг на друга, и что-то не сработает.
- Создайте уникальное имя функции для каждого вызова JSONP и используйте замыкание функции, связанное с этим именем функции, для подключения идентификатора к обратному вызову.
Вот пример третьего варианта.
Вы можете использовать замыкание, чтобы отслеживать переменную для вас, но, поскольку вы можете иметь несколько вызовов JSON в полете одновременно, вы должны использовать динамически генерируемое глобально доступное имя функции, уникальное для каждого последующего JSONP. вызов. Это может работать так:
Предположим, ваша функция, генерирующая тег для JSONP, выглядит примерно так (вы заменяете все, что используете сейчас):
function doJSONP(url, callbackFuncName) {
var fullURL = url + "&" + callbackFuncName;
// generate the script tag here
}
Тогда у вас может быть другая функция, которая делает это:
// global var
var jsonpCallbacks = {cntr: 0};
function getDataForId(url, id, fn) {
// create a globally unique function name
var name = "fn" + jsonpCallbacks.cntr++;
// put that function in a globally accessible place for JSONP to call
jsonpCallbacks[name] = function() {
// upon success, remove the name
delete jsonpCallbacks[name];
// now call the desired callback internally and pass it the id
var args = Array.prototype.slice.call(arguments);
args.unshift(id);
fn.apply(this, args);
}
doJSONP(url, "jsonpCallbacks." + name);
}
Ваш основной код будет вызывать getDataForId()
, и обратному вызову, переданному ему, будет передано значение идентификатора, подобное этому, с последующими другими аргументами, которые JSONP имеет для функции:
getDataForId(123, "http://remote.host.com/api?id=123", function(id, /* other args here*/) {
// you can process the returned data here with id available as the argument
});