【问题标题】:chaining sequential api calls and returning the data to be sorted链接顺序 api 调用并返回要排序的数据
【发布时间】:2022-02-17 06:01:16
【问题描述】:

我正在构建一个 Express REST api。在 GET 中,我希望能够进行如下所示的 api 调用,然后对于每个结果,使用结果中的值作为参数在不同的端点(未显示)调用相同的 api。

我无法弄清楚如何将此处显示的 api 调用与另一个调用定位到不同的端点,以便第二个调用等待第一个调用完成。我认为在这里使用“then”方法会有所帮助。

我也想知道是否有另一种在不使用显示的块逻辑的情况下获取数据的方法。理想情况下,这将是两个连续 api 调用的干净实例化,然后能够在返回数据之前对返回的数据进行排序。现在我知道它有点乱,任何关于更清洁的方法的建议都会很棒。

const express = require('express');
const router = express.Router();
const https = require('https');

const url = '/https://github.com/:user/:reponame'

router.get(url, async function (req, res) {
    const user = req.params.user;
    const reponame = req.params.reponame;
    const options = {
        hostname: 'api.github.com',
        path: '/repos/' + user + '/' + reponame + '/commits',
        headers: {
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1521.3 Safari/537.36'
        },
        OAUth: <key>
    }   


    https.get(options, function (apiResponse) {
        let data = '';

        // a data chunk has been received.
        apiResponse.on('data', (chunk) => {
          data += chunk;
        });
      
        apiResponse.on('end', () => {
          res.send(JSON.parse(data))
        });
       
    }).on('error', (e) => {
        console.log(e);
        res.status(500).send('Error');
    })
})//2nd api call here?

module.exports = router;```

【问题讨论】:

  • 您要么将 https.get 包装到 Promise 中,要么使用像 axiosgot 这样的库
  • @Anatoly 我尝试了几种方法。你能举一个将它包装在承诺中的例子吗? let firstCall = new Promise((resolve, reject) => { https.get(options, function (apiResponse) { resolve(data) }) firstCall.then(function(data){ console.log('data in then',数据) });
  • 这是一种反模式,因为每个端点必须做一件事来分离关注点。一个graphql就是答案

标签: node.js rest express asynchronous


【解决方案1】:

您需要使用 Promise 将这个带有回调的 https.get 函数转换为异步函数(例如,参见这个 answer)。

async function getAsync(options) {
  return new Promise((resolve, reject) => {
https.get(options, function (apiResponse) {
        let data = '';

        // a data chunk has been received.
        apiResponse.on('data', (chunk) => {
          data += chunk;
        });
      
        apiResponse.on('end', () => {
          resolve(data);
        });
       
    }).on('error', (e) => {
        reject(e);
    })
  })
}

用法:

try {
  const data = await getAsync(options);
} catch(err) {
  console.error(err);
  res.status(500).send('Error');
  return;
}
try {
  const anotherData = await getAsync(anotherOptions);
} catch(err) {
  console.error(err);
  res.status(500).send('Another error');
  return;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-16
    • 1970-01-01
    • 1970-01-01
    • 2019-06-12
    • 1970-01-01
    • 2021-07-20
    • 2018-11-09
    相关资源
    最近更新 更多