node异步请求不异步?
发布于 5 年前 作者 sjywz 3517 次浏览 来自 问答

用node测试同时发起请求,同时发起1000个,请求时间远远单个最久的请求时间。按道理,最大耗时不应该是其中单个的最久耗时么?但好像并不是这么回事?求大佬解惑

const request = require('request');

function _request(url,data,callFun){
    request({
        url: url,
        method: "POST",
        json: true,
        headers: {"content-type": "application/json"},
        body: data,
    }, (error, response, body) => {
        callFun && callFun(error,response,body);
    });
}

function _send(start,len = 1000){
    let url = 'https://www.baidu.com';
    return new Promise((resolve,reject) => {
        let max = start + len, 
            sendResult = {success:0,fail:0};
        for(let _i = start; _i <= max; _i++){
            let data = {_i};
            _request(url,data,function(err,res,body){
                let _r = Math.ceil(Math.random()*2) - 1;
                if(_r){
                    sendResult.success++;
                }else{
                    sendResult.fail++;
                }
                if(_i === max){
                    resolve(sendResult);
                }
            });
        }
    });
}

async function test(){
    let sT = new Date().getTime();
    let userLen = 5000,
        limit = 1000;
        sp  = Math.ceil(userLen / limit);
    
    for(let i = 0; i < sp; i++ ){
        let _sT = new Date().getTime();
        let _start = i*limit;
        let result = await _send(_start,limit);
        let _eT = new Date().getTime();
        console.log(result);
        console.log('本轮执行完毕,耗时:' + (_eT - _sT));
    }

    let eT = new Date().getTime();
    console.log('全部执行完毕,共耗时:' + (eT - sT));
}

test();
1 回复

想要异步同时发的就不要等就好了


+  const pList = []
    for(let i = 0; i < sp; i++ ){
+       const p = (async function () {
            let _sT = new Date().getTime();
            let _start = i*limit;
            let result = await _send(_start,limit);
            let _eT = new Date().getTime();
            console.log(result);
            console.log('本轮执行完毕,耗时:' + (_eT - _sT));
+      })()
+     pList.push(p)
    }
+   await Promise.all(pList)

这样就好了,不过你这个代码问题挺大的,比如

if(_i === max){
          resolve(sendResult);
  }

上面这个_i === max,只能保证最后一个运行完,而不能保证全部运行完成,还有封装Promise方法最好到最小执行单元比如在_request方法封装Promise运行时间分片就会好很多

回到顶部