Skip to content

Instantly share code, notes, and snippets.

@yyx990803
Last active May 19, 2023 23:17
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save yyx990803/5084020 to your computer and use it in GitHub Desktop.
Save yyx990803/5084020 to your computer and use it in GitHub Desktop.
连续请求ajax API回调顺序的问题
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script>
// coolshell api
function xss_ajax(url, callback) {
var script_id = null;
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', url);
script.setAttribute('id', 'coolshell_script_id');
script.onload = script.onreadystatechange = function(){
if((!this.readyState || this.readyState === "loaded" || this.readyState === "complete")){
callback && callback();
}
};
script_id = document.getElementById('coolshell_script_id');
if(script_id){
document.getElementsByTagName('head')[0].removeChild(script_id);
}
// Insert <script> into DOM
document.getElementsByTagName('head')[0].appendChild(script);
}
var xss_callbacks = {} // 容纳callbacks
function xss_rpc_call(n, callback) {
// 设置对应的jsonp callback
var callbackName = encodeURI('xss_callbacks[' + n + ']');
var url = "http://coolshell.cn/t.php?n="+n+"&callback="+callbackName;
xss_ajax(url);
// 现在每一次请求对应一个不同的callback
xss_callbacks[n] = function(result){
callback && callback(result);
}
}
</script>
</head>
<body>
<div id="result"></div>
<script>
var resultEl = document.getElementById('result')
function async (x) {
var responses = [],
completed = 0
for (var i = 0; i < x; i++) {
(function (i) {
xss_rpc_call(i, function (res) {
responses[i] = res
completed++
if (completed === x) done(x)
})
})(i)
}
function done (x) {
var result = ''
for (var i = 0; i < x; i++) {
result += i + ' ' + responses[i] + '<br>'
}
resultEl.innerHTML = result
callbacks = {} // 重置callbacks
}
}
async(20)
</script>
</body>
</html>
var responses = [],
completed = 0
function foo (x) {
for (var i = 0; i < x; i++) {
(function (i) {
var order = i
callRemote(i, function (res) {
responses[i] = res
completed++
if (completed === x) {
done(x)
}
})
})(i)
}
}
function done (x) {
responses.forEach(function (res) {
console.log(res)
})
}
// fake remote
function callRemote (x, callback) {
setTimeout(function () {
callback(x + ' : ' +Date.now())
}, Math.random() * 300 + 300)
}
foo(20)
// Example output
//
// 0 : 1362499999361
// 1 : 1362499999290
// 2 : 1362499999267
// 3 : 1362499999433
// 4 : 1362499999309
// 5 : 1362499999442
// 6 : 1362499999306
// 7 : 1362499999223
// 8 : 1362499999411
// 9 : 1362499999265
// 10 : 1362499999274
// 11 : 1362499999332
// 12 : 1362499999243
// 13 : 1362499999473
// 14 : 1362499999230
// 15 : 1362499999233
// 16 : 1362499999443
// 17 : 1362499999227
// 18 : 1362499999454
// 19 : 1362499999479
@haoel
Copy link

haoel commented Mar 4, 2013

试了一下,应该是错的。
——————————————
是我API的问题没有写好,现在对了!牛!

@yyx990803
Copy link
Author

问题出在提供的xss_rpc_call上面。看下round2.html中对于xss_rpc_call的修正。原始版本中xss_rpc_callback被注册为全局函数,每次xss_rpc_call被调用,xss_rpc_callback都被覆盖。这导致异步处理结果变得不可能。

@yyx990803
Copy link
Author

第一天的代码本身没有问题。原场景的需求比较模糊,没说清楚发送到api的应该是i还是x,略作修正。添加了node下的命令行输出。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment