也就是,第一大步有N个ajax请求,每个分别回调,每个回调又有N个ajax请求,现在是N*2个请求。
然后第三大步又是N*N个请求的回调各有N个请求,现在是N的三次方个请求。
这样一直到第五步,形成N的5次方个请求。
我希望的是:
1、不要等第一步的五个请求都完成,再去进入第二大步,我希望每个链条能有多快就有多快。每一大步的任意一个请求完成,它个人都立即进入后一步,而不是等大步内的N个请求都完成才进入下一步。
2、每一个请求get到的数据都要传递给该请求的下一步。
用promise的写法怎么写?
希望看到伪代码。
可以先将ajax转换成promise的方式,然后分步调用.
var ajax_1_1 = promise,
ajax_2_1 = promise,
...
ajax_n_1 = promsie;
var AJAX_1 = ajax_1_1.then( return ajax_1_2 ).then( return ajax_1_3 )....then( return ajax_1_n ),
AJAX_2 = ajax_2_1.then( return ajax_2_2 ).then( return ajax_2_3 )....then( return ajax_2_n ),
...
AJAX_n = ajax_n_1.then( return ajax_n_2 ).then( return ajax_n_3 )....then( return ajax_n_n );
Promise.all([AJAX_1,AJAX_2,...,AJAX_n])
.then(all promise done);
Promsie.all等所有的promise链完成调用之后才触发.
仔细想了一下,似乎没必要用promise这么复杂的东西。
假设有任意四个自然数,比如1,3,4,7。
假设已经有一个服务器实现了ajax,服务器所做的事情就是把post来的数据加1,然后返回给客户端。
当客户端得到数据之后,把数据分别乘以1、2、3、4,然后分别发送到服务器。这么循环下去。
如果裂变5次,就是一共发送4 + 4x4 + 4x4x4 + 4x4x4x4 + 4x4x4x4x4次。
似乎并不用promise,用递归函数即可。
(假设已经引入jQuery):
var fourNumerial = [1,3,4,7];
function post(numerial, level, index) {
if ( level <= 5 ) {
$.post('server.php', {numerial:numerial}, function(data) {
console.log('level:' + level + ' data:' + data + ' index:' + index);
for (var i = 1; i < 5; i++) {
post(data * i, level + 1, i);
}
});
}
}
for (var i = 0; i < 4; i++) {
post(fourNumerial[i], 1, i);
}
我感觉强行用promise属于添乱。
如果是用promise.all和race都不能实现我说的每个链条互相独立的原则。
如果是用五个then连缀,最初的promise对象应该传递的是一个数组,数组就是服务器返回的四个数据。既然是一次性返回,那么仍然不能实现我说的每个链条互相独立的原则。
如果是用递归+promise,那么promise其实也是没必要的,最终还是递归就够了。
算了就这样吧。谢谢大家。
补充:偶尔看到了一篇回答https://segmentfault.com/q/10... ,递归+promise,例子非常好,但是其实用promise只是为了证明promise确实可以这么用,但是实践中能不用还是不用吧。。
问出这个问题,说明你对promise
的使用还并不清楚。
说白了,你就是想要实现若干个互相之间不会相互干扰的操作链,不要用一个大步
这样的描述,你首先就把自己给绕晕了。
每个操作后续都有N个操作,每个操作之间相互独立,每个操作完成立即执行它自己的后续。
单一的顺序操作链是这样的:
start()
.then()
.then()
.then()
在promise的操作中,每一步都必须要要返回一个新的promise
,为什么要这样做?想明白这个问题,你就知道怎么做了。
理论上每个promise
都可以链接无数个后续动作,想要链接多个动作,这么写就行了:
start = new Promise(/*code*/);
move1 = start.then(/*code*/);
move2 = start.then(/*code*/);
move11 = move1.then(/*code*/);
move12 = move1.then(/*code*/);
move21 = move2.then(/*code*/);
move22 = move2.then(/*code*/);
start
后面接了move1
和move2
move1
后面接了move11
和move12
move2
后面接了move21
和move22
写段简单的代码:
function delay(time, value) {
return(new Promise(function executor(resolve) {
setTimeout(function asyn() {
console.log(value);
resolve();
}, time);
}));
}
function log1(value) {
return function handler() {
return delay(3000, value)
};
}
function log2(value) {
return function handler() {
return delay(1000, value)
};
}
let start = log2("start:")(),
move1 = start.then(log1('Step 1;')),
move2 = start.then(log2('Step 2;')),
move11 = move1.then(log1('Step 1.1;')),
move12 = move1.then(log1('Step 1.2;')),
move21 = move2.then(log2('Step 2.1;')),
move22 = move2.then(log2('Step 2.2;'));
按你的意思第一大步并不依赖上一大步的所有结果,如果是这样,
试试看下面的模拟代码,可以到Console中直接运行
//模拟ajax请求,sp 只是为了区别现在是第几步用的
var ajax_test = function(v,sp){
return new Promise(function(ok,no){
setTimeout(function(){
console.log(v + " -> " + sp + ' --ok')
var str = v+"."+sp
ok([str+'_1',str+'_2']);
},Math.random()*1000)
})
}
var ajax1_Promise = function(a){
return ajax_test(a,1).then(function(arr){
var p1 = ajax2_Promise(arr[0]);
var p2 = ajax2_Promise(arr[1]);
//每一步要裂变几个都可以
return Promise.all([p1,p2])
})
}
var ajax2_Promise = function(a){
return ajax_test(a,2).then(function(arr){
var p1 = ajax3_Promise(arr[0]);
var p2 = ajax3_Promise(arr[1]);
return Promise.all([p1,p2])
})
}
var ajax3_Promise = function(a){
//假设第三步最后一步
return ajax_test(a,3)
}
var arr = ["A","B"]
var arr_p = [];
arr.forEach(function(v){
arr_p.push(ajax1_Promise(v))
})
Promise.all(arr_p).then(function(d){
console.log(d);
console.log("all ok")
})
结果类似这样
B -> 1 --ok
A -> 1 --ok
A.1_2 -> 2 --ok
A.1_2.2_1 -> 3 --ok
A.1_1 -> 2 --ok
A.1_1.2_2 -> 3 --ok
A.1_2.2_2 -> 3 --ok
B.1_2 -> 2 --ok
B.1_1 -> 2 --ok
B.1_2.2_1 -> 3 --ok
A.1_1.2_1 -> 3 --ok
B.1_2.2_2 -> 3 --ok
B.1_1.2_1 -> 3 --ok
B.1_1.2_2 -> 3 --ok
[Array[2], Array[2]]
all ok