【问题标题】:Maximum allowed concurrent requests threshold was breached超出允许的最大并发请求阈值
【发布时间】:2022-01-27 11:33:15
【问题描述】:

我正在从 XML API 检索数据。为了将结果呈现到屏幕上,我必须调用一个端点来获取数据列表,然后我必须映射项目列表并为每个返回的项目调用第二个端点。第一个请求成功通过;但是其余的请求似乎是同时调用的。这导致大约 90% 的请求返回以下错误:

Maximum allowed concurrent requests threshold(10) was breached

我调用 API 端点的后端函数将 XML 作为字符串接收,并将响应转换为 JSON。代码如下:

export function newSoapRequest(options = {
    method: "POST",
    url: "",
    headers: {},
    xml: "",
    timeout: 10000
}) {
    const {
        method,
        url,
        headers,
        xml, // soap envelope as string
        timeout
    } = options

    return new Promise((resolve, reject) => {
        axios({
            method: method || "POST",
            url,
            headers,
            data: xml,
            timeout
        }).then((res) => {
             resolve({
               res: {
                    headers: res.headers,
                    body: XML.parse(res.data), 
                    statusCode: res.status,
                }
            })
        }).catch((err) => {
            if(err.response) {
               reject(err.response.data)
            } else {
               reject(err)
            }
        })
    })
}

这是我从地图函数调用 API 的代码

resortList.map(async (resort) => {
            let resortXML = `<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:dae="DAE"><soapenv:Header/><soapenv:Body><dae:DAEGetResortProfile><!--Optional:--><dae:AuthID>GWAYUAT</dae:AuthID><!--Optional:--><dae:EndpointID>${resort.WeekEndpointID}</dae:EndpointID><!--Optional:--><dae:ResortID>${resort.ResortId}</dae:ResortID></dae:DAEGetResortProfile></soapenv:Body></soapenv:Envelope>`
            await newSoapRequest({method: "POST", url, headers: sampleHeaders, xml: resortXML, timeout: 10000})
            .then(response => console.log(response))
            .catch(err => console.log(err))
        })

据我所知,响应是从 newSoapRequest 函数发送的,然后连接关闭。当我在 map 函数中使用 async await 时,map 函数应该等到请求完成并关闭连接,然后再处理响应,然后第二次运行。这个问题可能与它本身的地图功能有关吗?还是我的 newSoapRequest 函数没有正确关闭连接?

【问题讨论】:

    标签: javascript post axios xmlhttprequest


    【解决方案1】:

    Array.prototype.map 函数会等待直到异步函数结束。这就是同时调用所有项目的原因。

    为避免这种情况,您可以使用以下方法:

    const numbers = Array.from({ length: 10 }).map((_, i) => i + 1);
    const callback = async n => await new Promise(r => setTimeout(() => r(`${n} * 2 = ${n * 2}`), 10));
    
    async function sequentialAsyncMap(arr, predicate) {
      const result = [];
      for (const item of arr) {
        result.push(await predicate(item));
      }
    
      return result;
    }
    
    sequentialAsyncMap(numbers, callback)
      .then(console.log);

    callback-chunk 包示例(免责声明:我是此包的作者):

    const chunk = require('callback-chunk');
    const callbacks = resortList.map(item => () => newSoapRequest({
      method: 'POST',
      url,
      timeout: 10000,
      headers: sampleHeaders,
      xml: `<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:dae="DAE"><soapenv:Header/><soapenv:Body><dae:DAEGetResortProfile><!--Optional:--><dae:AuthID>GWAYUAT</dae:AuthID><!--Optional:--><dae:EndpointID>${item.WeekEndpointID}</dae:EndpointID><!--Optional:--><dae:ResortID>${item.ResortId}</dae:ResortID></dae:DAEGetResortProfile></soapenv:Body></soapenv:Envelope>`
    }));
    
    const items = await chunk(callbacks, 10, console.log);
    

    【讨论】:

    • 我尝试将地图包装在 Promise.all 函数中。现在更多的请求成功完成,但仍然只占我发出的请求总数的 30% 左右。
    • @Alex Promise.all 不会使请求连续,只是等待所有请求完成。作为另一种解决方案,您可以进行批量请求,一次请求 10 个,然后获取结果。有一个 npm 包可以做到这一点:callback-chunk。 (免责声明:我制作了这个包)。
    • 感谢您的建议。我安装了您的建议并更新了我的地图功能。但是每次我运行块函数时,我都会收到一个控制台错误,上面写着“回调不是函数”。这是我的地图功能:resortList.map(resort =&gt; { let resortXML = "soap data" callbacks.push(() =&gt; new Promise(resolve =&gt; { newSoapRequest({method: "POST", url, headers: sampleHeaders, xml:resortXML, timeout: 10000}) .then((res) =&gt; { resolve(res.body) }) })) })
    • 然后我调用块函数:await chunk(callbacks, 10, console.log)
    • 当我 console.log 回调时,它告诉我它确实是一个函数数组
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-07-03
    • 2019-02-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-01
    • 2018-02-27
    • 1970-01-01
    相关资源
    最近更新 更多