javascript - promise写异步,比如5大步,每步都并发N个ajax请求,像裂变一样形成(N的5次方)个请求,怎么写?
PHPz
PHPz 2017-04-11 09:49:30
[JavaScript讨论组]

也就是,第一大步有N个ajax请求,每个分别回调,每个回调又有N个ajax请求,现在是N*2个请求。

然后第三大步又是N*N个请求的回调各有N个请求,现在是N的三次方个请求。

这样一直到第五步,形成N的5次方个请求。

我希望的是:
1、不要等第一步的五个请求都完成,再去进入第二大步,我希望每个链条能有多快就有多快。每一大步的任意一个请求完成,它个人都立即进入后一步,而不是等大步内的N个请求都完成才进入下一步。

2、每一个请求get到的数据都要传递给该请求的下一步。

用promise的写法怎么写?

希望看到伪代码。

PHPz
PHPz

学习是最好的投资!

全部回复(6)
黄舟

问出这个问题,说明你对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后面接了move1move2
move1后面接了move11move12
move2后面接了move21move22


写段简单的代码:

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;'));
ringa_lee

Promise.all() 并发执行

黄舟

这应该是一个单子变换的问题。

迷茫

我很好奇,什么样的应用场景需要并发这么多ajax请求?

阿神

可以先将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链完成调用之后才触发.

PHPz

按你的意思第一大步并不依赖上一大步的所有结果,如果是这样,
试试看下面的模拟代码,可以到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
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号