猿问

如何异步调用 3 个请求?

我必须做一个功能来测试 3 个 API 是否正在运行。因此,用户将单击“测试 API”按钮,它将返回每个 API 的状态(状态:200、500、404 等)。如果 API 返回错误,我应该显示错误堆栈。屏幕示例:


API       Status      Detail

url1.com   200          -

url2.com   200          -

url3.com   500     internal server error

我的问题是,如何并行调用 3 个请求并返回异步结果,我的意思是如何更新 API 请求状态的屏幕而不必等待所有请求的结果


我是基于如何按顺序调用三个请求?,但它同步返回结果。


*******编辑*****


那是我当前的代码


app.get('/testDependencies', function (req, res, next) {    


    let objTestsResul = {}        

    var urls = ['url1', 'url2', 'url3'];

    let index = 0

    while(urls.length > 0) {

      let url = urls.shift();

      objTestsResult[index++] = testURL(url)


   }


    res.send(objTestsResult)

});

这个函数对于每个 URL 都是一样的:


function testURL(URL){


   fetch(URL, {

        method: 'GET'      

    })

        .then(res => {

            res.json()            

        })

        .then(json => {

            console.log(json)

            return json      

         })

        .catch(error => {            

            return error

          })

}


智慧大石
浏览 194回答 3
3回答

临摹微笑

Promises( mdn ) 似乎是你要找的。它们本质上是一个更具可读性的回调版本,它允许您在发生其他事情时执行代码,而不必在恢复执行之前等待该触发器发生。let endpoint1 = () => new Promise(resolve => setTimeout(() => resolve('200'), 1000));&nbsp; let endpoint2 = () => new Promise(resolve => setTimeout(() => resolve('201'), 2000));&nbsp; let endpoint3 = () => new Promise(resolve => setTimeout(() => resolve('500'), 1500));&nbsp; document.getElementById('test').addEventListener('click', () => {&nbsp; &nbsp; document.getElementById('status').textContent = 'test running...';&nbsp; &nbsp; Promise.all([&nbsp; &nbsp; &nbsp; endpoint1().then(a => document.getElementById('result1').textContent = a),&nbsp; &nbsp; &nbsp; endpoint2().then(a => document.getElementById('result2').textContent = a),&nbsp; &nbsp; &nbsp; endpoint3().then(a => document.getElementById('result3').textContent = a),&nbsp; &nbsp; ]).then(() => document.getElementById('status').textContent = 'test complete');&nbsp; });<button id="test">test</button><div>status: <span id="status">not running</span></div><div>endpoint 1: <span id="result1"></span></div><div>endpoint 2: <span id="result2"></span></div><div>endpoint 3: <span id="result3"></span></div>

吃鸡游戏

如果您可以使用Bluebird,这实际上非常简单:const { Promise } = require('bluebird');app.get('/testDependencies', function (req, res, next) {&nbsp; &nbsp;&nbsp;&nbsp; Promise.map(['url1', 'url2', 'url3'], url => testURL(url)).then(results => {&nbsp; &nbsp; &nbsp;res.send(results);&nbsp; });});您只需要确保您的承诺函数实际返回一个承诺:function testURL(URL) {&nbsp; let start_time = new Date().getTime();&nbsp; &nbsp;&nbsp; return fetch(URL, {&nbsp; &nbsp; method: 'GET'&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; }).then(res => {&nbsp; &nbsp; res.json()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; }).then(json => {&nbsp; &nbsp; console.log(json)&nbsp; &nbsp; return json&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; }).catch(error => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; return error&nbsp; })}Promise 不能被依赖链接,除非您从链接中涉及的函数中明确返回它们。如果您能够使用asyncand await,我还建议您这样做,并且可以极大地简化其他复杂的代码。

至尊宝的传说

Express 无法发送多个响应。您必须完成所有调用或用于WebSockets流式传输数据。function testURL(URL) {&nbsp; return new Promise((resolve, reject) => {&nbsp; &nbsp; if (URL === 'url2') {&nbsp; &nbsp; &nbsp; reject(new Error('Internal Server Error'));&nbsp; &nbsp; &nbsp; return;&nbsp; &nbsp; }&nbsp; &nbsp; resolve({ status: 200 });&nbsp; });}const main = async () => {&nbsp; const urls = ['url1', 'url2', 'url3'];&nbsp; // return resolved and rejected Promises because if one fails in Promise.all&nbsp; // the function will throw and we won't have any access to any resolved Promises.&nbsp; const results = await Promise.all(urls&nbsp; &nbsp; .map(url => testURL(url).then(response => response).catch(error => error)));&nbsp; // every error have a stack property, Set the status to whatever you want&nbsp; // based on the error and store the stack and the message&nbsp; const objTestsResul = results.reduce((result, cur, i) => {&nbsp; &nbsp; result[urls[i]] = cur.stack&nbsp; &nbsp; &nbsp; ? { status: 500, message: cur.message, stack: cur.stack }&nbsp; &nbsp; &nbsp; : cur;&nbsp; &nbsp; return result;&nbsp; }, {});&nbsp; console.log(objTestsResul);};main();
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答