【问题标题】:Node.js / Koa: wait for API call before responseNode.js / Koa:在响应之前等待 API 调用
【发布时间】:2020-03-05 15:10:59
【问题描述】:

我只有基本的 JS 知识(主要是 jQuery),所以这可能是一个非常简单的知识。 并且确实意识到性能方面它可能不是最好的解决方案,但现在这只是概念证明。

我有这个简单的 Koa 应用程序。我要做的就是在访问 /callapi 路由时调用外部 API(Airtable),并将 API 响应中的一些数据添加到 ctx.body。

但是,我在转到 http://localhost:3000/callapi 时收到 404 Not Found 我理解这可能是因为API调用是异步的,所以Node.js / Koa不等待它完成并继续执行,但是没有代码在其他地方设置响应体,所以它导致404。

我怎样才能做到这一点? 如果需要,很高兴使用其他路由中间件或其他中间件。

我相信带有 async/await 的 Promise 是 Koa 所接受的新方法,所以如果我能以某种方式添加/包装它,我猜这将是最好的。

const KoaRoute = require('koa-route');
const Koa = require('koa');
const app = new Koa();

var Airtable = require('airtable');
var base = new Airtable({apiKey: 'keyI6rZxwsXXXXXXX'}).base('appXXXXXX');


app.use(KoaRoute.get('/callapi', async function (ctx) {
    await base('Couples').find('reclnxjiMeSljrzP0', function(err, record) {
        console.log('Retrieved', record.id);
        ctx.body = "Record ID from API: " + record.id;
    });
}));


app.listen(3000);
console.log('listening on port 3000');

【问题讨论】:

  • 当你声明的路由显示 /callapi 时,你为什么要点击 /testapi?
  • @Waldemar,请像这样使用async - async ctx => await your_api();
  • @CoryRobinson 抱歉,这是一个错字。已编辑。
  • @AllenHaley 我编辑了上面的代码尝试等待/异步,但仍然没有运气。我可能没有正确理解整个 await / async 语法。如果您可以编辑整个相关代码块,那就太好了……真的很努力。 API 调用本身运行良好 - console.log('Retrieved', record.id);显示来自 API 的有效信息。
  • @Waldemar,我添加了答案,但不确定返回值是什么。如果只返回记录或其他值,请检查返回值。

标签: javascript node.js async-await koa


【解决方案1】:

看起来await 是错误的。请试试这个。

...
app.use(KoaRoute.get('/callapi', async function (ctx) {
    /* please check return value if it returns correct value. */
    try {
        const record = await getBase();
        console.log('Retrieved', record.id);
        ctx.body = "Record ID from API: " + record.id;
    } catch (err) {
        // handle exception
    }
}));
...

已编辑:请添加以下功能,然后再试一次。

function getBase() {
    return new Promise((resolve, reject) => {
        base('Couples').find('reclnxjiMeSljrzP0', function(err, record) {
            console.log('Retrieved', record.id);
            if (err) {
                reject(err)
            } else {
                resolve(record);
            }
        });
    });
}

【讨论】:

  • 不幸的是,base(...).find(...) 方法没有从 API 返回记录。也许有一种方法可以将 base(...).find(...) 调用“包装”成某种东西,以使执行首先等待它完成?可以说是让它兼容等待/同步吗?
  • @Waldemar,我通过添加另一个异步获取 bases 的函数来更新答案。
猜你喜欢
  • 2018-11-16
  • 2021-11-18
  • 2014-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-02
  • 2021-04-17
相关资源
最近更新 更多