首页 > 解决方案 > Node.JS Airtable - Await 不等待 promise 被解决

问题描述

我正在尝试从我的 node.js 应用程序中的 Airtable 获取数据,但在我的承诺解决后我无法获得我的结果。

这是我的代码:

async function getData(code) {
  return await airtableBase("Data")
    .select({
      filterByFormula: `{code} = "${code}"`,
    })
    .firstPage((err, records) => {
      if (err) {
        console.log(err);
        return {};
      }

      console.log(records[0].fields);
      return records[0].fields;
    });
}
stuff.map(async (object) => {
      embedData = getEmbedData(object);

      data = await getData(embedData.code);

      console.log(data);
})

这是我记录的内容:

undefined
undefined
undefined
{
  code: '1',
  fullname: 'Test 1',
  logo: '...'
}
{
  code: '2',
  fullname: 'Test 2',
  logo: '...'
}
{
  code: '3',
  fullname: 'Test 3',
  logo: '...'
}

标签: javascriptnode.jsasynchronousasync-await

解决方案


你假设

airtableBase(...).select(...).firstPage((error, result) => {})

返回一个 Promise - 它没有

很少有采用节点样式回调的函数......即

function(error, result) 

返回一个承诺

更改 getData 以返回 Promise

function getData(code) {
    return new Promise((resolve, reject) => {
        airtableBase("Data")
        .select({
            filterByFormula: `{code} = "${code}"`,
        })
        .firstPage((err, records) => {
            if (err) {
                console.log(err);
                return reject({});
            }
            console.log(records[0].fields);
            resolve(records[0].fields);
        });
    });
}

也,与

stuff.map(async (object) => {
      embedData = getEmbedData(object);

      data = await getData(embedData.code);

      console.log(data);
})

不能保证订单是正确的,在这种情况下可能是正确的,但不能保证

上面写的比较好

Promise.all(stuff.map((object) => {
    embedData = getEmbedData(object);
    return getData(embedData.code);
}))
.then(results => {
    results.forEach(item => console.log(item));
})

或者如果该代码在async函数中

const results = await Promise.all(stuff.map((object) => {
    embedData = getEmbedData(object);
    return getData(embedData.code);
}))
results.forEach(item => console.log(item));

注意:绝对没有拒绝测试,因为您的代码没有,但实际上,您应该尝试/catch(如果使用 async/await)或 .catch 如果使用 .then


请注意,如果没有给出回调函数,实际上.firstPage 可能会返回一个 Promise,因此您的代码可能更简单

function getData(code) {
    return airtableBase("Data")
    .select({
        filterByFormula: `{code} = "${code}"`,
    })
    .firstPage()
    .promise() /* this could be needed, again, depending on the library */
    .then(records => {
        return records[0].fields;
    });
}

但是,由于您没有说明您正在使用的 db 库的任何内容,我不能确定上述内容是否有效


推荐阅读