【问题标题】:Synchronous JSONP request同步 JSONP 请求
【发布时间】:2023-04-09 00:32:02
【问题描述】:

关于 JSONP 请求以及它们不能同步发出的事实存在许多问题。大多数解决方法都涉及使用回调或 ajax 请求中的成功函数来执行您想要的操作,但我认为这对我不起作用。

背景:我正在使用Solr 开发一个搜索应用程序。我正在开发一个 javascript API 供其他人用来与 Solr 交互,因此他们不需要了解 Solr 搜索请求的来龙去脉。

在我的 api 中,我有一个 Request 对象,带有一个名为 doRequest 的函数。该函数的目的是执行对 solr 服务器的调用(在另一个域上,因此需要 JSONP),并返回一个 Response 对象。

Request.prototype.doRequest = function (){
var res = new Response();
$.ajax({
    url: this.baseURL,
    data: 'q=*:*&start=0&rows=10&indent=on&wt=json', 
    success: function(data){
        res.response = data.response;
        res.responseHeader = data.responseHeader;
        /*
          other...
          stuff...
        */
    },
    dataType: 'jsonp',
    jsonp: 'json.wrf'
});
res.request = this;
return res;
};

“用户”会像这样使用这个函数......

var req = new Request();
var res = req.doRequest();

然后对 res 中的结果做某事或其他事情。

鉴于我无法执行同步 JSONP 请求,并且无法从 ajax 函数中返回,因此无论如何我都无法确保在用户开始使用 res 之前为他们完全填充它。

谢谢,

【问题讨论】:

  • 为什么您需要保护您的用户不必编写回调函数?这么多 Javascript 需要了解如何异步执行操作,您只能让新手远离它这么久......
  • 异步具有传染性。一旦您的控制流的一部分使用回调,您的控制流的其余部分也将使用回调。恐怕没有办法解决这个问题。 Javascript 的乐趣和恐惧之一。
  • 其实是有办法绕过的,不过需要编译步骤:npmjs.org/package/streamline
  • @MattB.,我试图避免 Andrew 提到的问题。一旦你进入回调,你基本上必须永远坚持下去。
  • @CTC 我意识到使用回调稍微不那么简单(尽管我仍然认为它很容易学习)。但是,唯一的选择是在发出请求时阻止接口,但是您可以设法使调用同步,这对用户体验不利。这就是为什么我认为即使像 jQuery 允许的那样执行同步 AJAX 请求也是一个坏主意。

标签: javascript ajax jsonp synchronous


【解决方案1】:

看起来使用回调函数是一种方法。如果您有兴趣,这就是我最终这样做的方式。

Request.prototype.doRequest = function (callback){
var res = new Response();
$.ajax({
    url: this.baseURL,
    data: 'q=*:*&start=0&rows=10&indent=on&wt=json', 
    success: function(data){
        res.response = data.response;
        res.responseHeader = data.responseHeader;
        res.request = this;
        /*
          other...
          stuff...
        */
        callback(res);
    },
    dataType: 'jsonp',
    jsonp: 'json.wrf'
});
};

现在用户像这样使用函数:

var req = new Request();
var res = req.doRequest(parseResults);

其中 parseResults 是用户定义的回调函数,以响应对象为参数。

function parseResults(res){
    //Doing work
}

【讨论】:

    【解决方案2】:

    无论您的程序的其余部分是否同步,有时您需要同步触摸 REST 接口。一个示例是,您请求获取一组资产(可能是资产 Id),然后对每个 Id 进行水合以获得完整的数据/资产。如果您使用过 Ooyala API,那么您就会明白我的意思。

    我创建了似乎是第一个同步 JSONP 模块,它允许每个下一个请求仅在其前一个请求完成后运行。它使用递归而不是 Promises,这意味着在前一个请求成功之前不会发送下一个请求。 API 在这里:https://github.com/cScarlson/jsonpsync

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2011-11-27
      • 2013-12-07
      • 2013-04-25
      • 2015-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-10
      • 1970-01-01
      相关资源
      最近更新 更多