为了账号安全,请及时绑定邮箱和手机立即绑定

如何异步调用 3 个请求?

如何异步调用 3 个请求?

智慧大石 2021-07-13 21:10:17
我必须做一个功能来测试 3 个 API 是否正在运行。因此,用户将单击“测试 API”按钮,它将返回每个 API 的状态(状态:200、500、404 等)。如果 API 返回错误,我应该显示错误堆栈。屏幕示例:API       Status      Detailurl1.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          })}
查看完整描述

3 回答

?
临摹微笑

TA贡献1982条经验 获得超2个赞

Promises( mdn ) 似乎是你要找的。它们本质上是一个更具可读性的回调版本,它允许您在发生其他事情时执行代码,而不必在恢复执行之前等待该触发器发生。


let endpoint1 = () => new Promise(resolve => setTimeout(() => resolve('200'), 1000));

  let endpoint2 = () => new Promise(resolve => setTimeout(() => resolve('201'), 2000));

  let endpoint3 = () => new Promise(resolve => setTimeout(() => resolve('500'), 1500));


  document.getElementById('test').addEventListener('click', () => {

    document.getElementById('status').textContent = 'test running...';

    Promise.all([

      endpoint1().then(a => document.getElementById('result1').textContent = a),

      endpoint2().then(a => document.getElementById('result2').textContent = a),

      endpoint3().then(a => document.getElementById('result3').textContent = a),

    ]).then(() => document.getElementById('status').textContent = 'test complete');

  });

<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>


查看完整回答
反对 回复 2021-07-15
?
吃鸡游戏

TA贡献1829条经验 获得超7个赞

如果您可以使用Bluebird,这实际上非常简单:


const { Promise } = require('bluebird');


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

  Promise.map(['url1', 'url2', 'url3'], url => testURL(url)).then(results => {

     res.send(results);

  });

});

您只需要确保您的承诺函数实际返回一个承诺:


function testURL(URL) {

  let start_time = new Date().getTime();   


  return fetch(URL, {

    method: 'GET'      

  }).then(res => {

    res.json()            

  }).then(json => {

    console.log(json)

    return json      

  }).catch(error => {            

    return error

  })

}

Promise 不能被依赖链接,除非您从链接中涉及的函数中明确返回它们。


如果您能够使用asyncand await,我还建议您这样做,并且可以极大地简化其他复杂的代码。


查看完整回答
反对 回复 2021-07-15
?
至尊宝的传说

TA贡献1789条经验 获得超10个赞

Express 无法发送多个响应。您必须完成所有调用或用于WebSockets流式传输数据。


function testURL(URL) {

  return new Promise((resolve, reject) => {

    if (URL === 'url2') {

      reject(new Error('Internal Server Error'));

      return;

    }

    resolve({ status: 200 });

  });

}


const main = async () => {

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


  // return resolved and rejected Promises because if one fails in Promise.all

  // the function will throw and we won't have any access to any resolved Promises.

  const results = await Promise.all(urls

    .map(url => testURL(url).then(response => response).catch(error => error)));


  // every error have a stack property, Set the status to whatever you want

  // based on the error and store the stack and the message

  const objTestsResul = results.reduce((result, cur, i) => {

    result[urls[i]] = cur.stack

      ? { status: 500, message: cur.message, stack: cur.stack }

      : cur;

    return result;

  }, {});


  console.log(objTestsResul);

};


main();


查看完整回答
反对 回复 2021-07-15
  • 3 回答
  • 0 关注
  • 193 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信