如何等待回调函数中的数据然后返回?

时间:2020-03-10 08:17:52

标签: node.js

我正在使用异步函数,试图从回调函数返回数据:

async function getData(){
    const client = new google.auth.JWT(
        keys.client_email,
        null,
        keys.private_key,
        ['https://www.googleapis.com/auth/spreadsheets']    
    )

    let returnData
    const finalData = (data) => {
        returnData = data
    }

    async function gsrun(client) {
        const gsapi = google.sheets({version:'v4', auth: client})

        const options = {
            spreadsheetId: '1d3ZiP1I9jJ2ddlD1Hx2ylWn1VFD_5lYQ9Ps9e9gEqI',
            range: 'Sheet1!A1:H5'
        }

        const data = await gsapi.spreadsheets.values.get(options)

        return data.data.values
    }

    client.authorize( async (err, tokens)=> {
        if(err) return console.log(err)
        let data = await gsrun(client)
        finalData(data)
    })

    return returnData
}

然后在控制台中得到:Promise {undefined}。我应该如何等待解决或等待数据的诺言?

2 个答案:

答案 0 :(得分:0)

您的client.authorize已经在等待gsrun()函数返回解析(我不确定gsrun()的拒绝处理方式,但是我建议您使用.then()处理解析/拒绝(如果未实现)一个try,catch语句)。

另一个问题是,尽管您正在等待gsrun(client),以下代码仍将运行

return returnData

因为它不在finalData()函数中。我建议您只执行已设置的状态。

这里显示的是returnData是在分配数据之前返回的

function returnPromise() {
    return new Promise((resolve, reject) => {
      setTimeout(()=>{
        resolve('Success')
      },2000)
      // reject('err')
    })
}

async function test(){
  returnPromise().then(
    resolve=>{console.log(resolve)},
    reject=>{console.log(reject)}
  )
}

test()
console.log('I COME HERE FIRST') // Executed first before promise is returned

这是一个如何实现拒绝处理的简单示例(仅供参考)

function gsrun() {
    return new Promise((resolve, reject) => {
      //resolve('Success')
       reject('err')
    })
}

async function authorizeCallback(){
    gsrun().then(
    resolve=>{finalData(resolve)},
    reject=>{console.log(reject)} // do error handling
  )
}

答案 1 :(得分:0)

在分配数据之前,您仍在尝试返回。在client.authorize调用回调之前,您不会“等待”,因为您不能这样做。如果回调被同步调用,则只能“从回调返回数据”。但事实并非如此。声明回调为async无关紧要,重要的是调用者(即client.authorize)如何/何时调用回调。

client.authorize包裹在promise中,并将await包裹在getData函数中。

async function gsrun(client) {
  const gsapi = google.sheets({
    version: 'v4',
    auth: client
  })

  const options = {
    spreadsheetId: '1d3ZiP1I9jJ2ddlD1Hx2ylWn1VFD_5lYQ9Ps9e9gEqI',
    range: 'Sheet1!A1:H5'
  }

  const data = await gsapi.spreadsheets.values.get(options)

  return data.data.values
}


function authorize(client) {
  return new Promise((resolve, reject) => {
    client.authorize((err, tokens) => {
      if (err) {
        reject(err);
      } else {
        resolve(tokens);
      }
    });
  });
}


async function getData() {
  const client = new google.auth.JWT(
    keys.client_email,
    null,
    keys.private_key, ['https://www.googleapis.com/auth/spreadsheets']
  )

  await authorize(client);
  return await gsrun(client);
}

如果认证失败,此处authorize将引发错误,如果认证成功,则返回令牌。


I wrote a post about callbacks and data。尽管它没有兑现承诺,但也许可以帮助您理解回调。