【问题标题】:How to wrap jsonP callback in native javascript Promise?如何在原生 javascript Promise 中包装 jsonP 回调?
【发布时间】:2015-05-15 06:04:26
【问题描述】:

我正在使用本机 Promise 将一堆 XmlHttpRequests 组合成一个结果,我认为我得到了它的工作,请参阅 http://jsfiddle.net/pjs06hdo/ (随机调用 flickr api,查看控制台以了解实际发生的顺序)

可能会有更短的实现,但通过这段代码我可以理解发生了什么。

但随后出现了愚蠢的 JSONP :-( 事实证明,实际的目标站点不允许跨站点请求,我必须使用提供的 jsonP 端点(再次用 flickr 模拟)我在这里卡住了:那个愚蠢的全局回调不符合我对Promise的基本理解

我认为解决方案与How do I convert an existing callback API to promises? 中的解释有关。

我试图实现它,但它只能部分工作:http://jsfiddle.net/b33bj9k1/ 没有实际输出,只有控制台消息,抱歉。但是你可以看到有三个调用来创建承诺,但resolve()jsonFlickrApiAsync() 只被调用一次。

使用 Promise 处理 jsonP 回调的正确方法是什么,以便我可以有一个 Promise.all() 来处理上述 XmlHttpRequest 版本中的结果?

请不要使用 jQuery - 我想了解实际情况

【问题讨论】:

  • 我认为您不能将promise 与 jsonp 一起使用。查看this similar answer
  • 我认为这个问题是相当无关的@KJPrice 我知道我不能用 xmlhttprequest 调用 jsonP 服务。根本没有提到Promise
  • 您必须在每次发出 JSONP 请求时使用不同的回调名称 - 否则在收到第一个响应之前,最后一个的函数将覆盖第一个的函数。跨度>

标签: javascript ajax jsonp es6-promise


【解决方案1】:

这不是 Promise 的问题,这是 JSONP 的问题。由于它使用全局回调,因此您需要为每个请求使用不同的回调 - 具有不同的名称。对于 Flickr,这意味着您必须使用 their jsoncallback url parameter。参数名称可能因您的实际端点而异。


但是,您对 Promise 的使用确实很奇怪。通常,您会为每个请求使用一个 Promise 来表示该请求的结果。您故意只创建一个全局承诺,这是行不通的。

function loadJSONP(url, parameter="callback") {
    var prop = "loadJSONP.back" + loadJSONP.counter++;
    var script = document.createElement("script");
    function withCleanUp(r) {
        return (x) => {
            loadJSONP[prop] = null;
            document.head.removeChild(script);
            r(x);
        }
    }
    return new Promise((resolve, reject) => {
        loadJSONP[prop] = withCleanUp(resolve);
        script.onerror = withCleanUp(reject);
        // setTimeout(script.onerror, 5000); might be advisable

        script.src = url+"&"+parameter+"="+prop;
        document.head.appendChild(script);
    });
}
loadJSONP.counter = 0;

【讨论】:

    猜你喜欢
    • 2014-06-28
    • 2020-01-07
    • 2015-10-06
    • 2015-12-25
    • 2014-12-24
    • 1970-01-01
    • 1970-01-01
    • 2014-05-10
    • 2011-09-27
    相关资源
    最近更新 更多