我正在使用原生Promise将一堆XmlHttpRequests合并到一个结果中,我认为我已将其运行,请参阅http://jsfiddle.net/pjs06hdo/ (随机调用flickr api,查看控制台实际按顺序进行的操作)
可能会有更短的实现,但使用此代码我可以理解正在发生的事情。
然后出现了愚蠢的JSONP :-(因为事实证明实际的目标站点不允许跨站点请求,我必须使用提供的jsonP端点(再次使用flickr模拟)并且在这里我' m卡住:这个愚蠢的全球回调不符合我对Promise
我认为解决方案与How do I convert an existing callback API to promises?中的解释有关。
我试图实现这个但它只能部分工作:http://jsfiddle.net/b33bj9k1/没有实际输出,只有控制台消息,抱歉。但是在那里你可以看到有三个调用来创建promise,但是resolve()
,jsonFlickrApiAsync()
只被调用一次。
使用Promise处理jsonP回调的正确方法是什么,所以我可以使用Promise.all()
处理结果,就像上面的XmlHttpRequest版本一样?
请不要jQuery - 我想了解最新情况
答案 0 :(得分:3)
这不是承诺的问题,这是JSONP的问题。由于它使用全局回调,因此您需要为每个请求使用不同的回调 - 具有不同的名称。对于Flickr,这意味着您必须使用their jsoncallback
url parameter。参数名称可能因实际终点而异。
然而,你对承诺的使用确实很奇怪。通常,您会为每个请求使用一个承诺来表示该请求的结果。您有意只创建一个全局承诺,但这无效。
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(scr);
});
}
loadJSONP.counter = 0;