异步等待使用和错误处理问题

Jer*_*lli 2 javascript node.js async-await

两个都尝试打印Promise { <pending> },第二个打印Unhandled Promise Rejection Warning.我已经成功使用了.then和.catch的Promises,但有些东西我想使用async/await以更多的同步方式进行编码.我可能会使用Yield吗?

try {
  var tokens = getNewTokens('refresh-token', 1)
  console.log(tokens)
} catch (error) {
  console.log(error.message)
}

try {
  tokens = getNewTokens('no-such-refresh-token', 1)
  console.log(tokens)
} catch (error) {
  console.log(error.message)
}

function getRefreshToken (refreshToken, userId) {
  return new Promise((resolve, reject) => {
    if (refreshToken === 'refresh-token' && userId === 1) {
      return resolve({
        refreshToken: 'refresh-token',
        accessToken: 'jwt'
      })
    } else {
      const error = Error('Refresh token not found')
      return reject(error)
    }
  })
}

async function getNewTokens (refreshToken, userId) {
  if (!refreshToken || !userId) {
    throw Error('Missing params')
  }
  try {
    var result = await getRefreshToken(refreshToken, userId)
  } catch (error) {
    throw Error(error.message)
  }
  if (!result) {
    throw Error('Something went bonk')
  }
  // Do stuff..
  // get user from DB
  // update refresh token with a new one
  // make new jwt
  return {
    user: {
      id: 1,
      name: 'Jerry',
      role: 'admin'
    },
    newRefreshToken: 'new-refresh-token',
    newAccessToken: 'new-jwt'
  }
}
Run Code Online (Sandbox Code Playgroud)

lon*_*day 18

使用asyncawait不会使你的整个程序异步.它使特定函数异步.最后,async是语法糖,使编写承诺代码更容易.

一个async函数返回Promise.调用异步函数的代码必须将其视为返回promise的函数.(唯一的例外是当调用async函数的代码本身在async函数中时,在这种情况下它可以是await编辑.)

所以抛出一个Error被转化为Promise拒绝.你不能在一个try..catch块中捕获它,原因很简单,因为try..catch在抛出错误之前它已经过了!(同样,例外情况是你从一个人那里调用它async函数.如果你是await一个异步函数,一个try..catch块将起作用.在这种情况下,try..catch块被视为添加一个Promise#catch函数.)

你最终必须从中捕获错误 async使用普通Promise#catch方法或第二个参数来函数中的Promise#then:

getNewTokens('no-such-refresh-token', 1)
    .then(function(tokens) {
        console.log(tokens);
    }, function(error) {
        console.log(error.message);
    });
Run Code Online (Sandbox Code Playgroud)


Ben*_*ard 8

我想将其提交为使用async / await处理错误的合理且易读的方式。

const value = await asyncFunction().catch(err => new Error(err))
if (value instanceof Error) return res.status(500).send('There was an error doing something')
Run Code Online (Sandbox Code Playgroud)

通过添加.catch()方法, 方法返回anError从而将其分配给 value 变量,我们可以确定变量中会存在一些值。唯一需要添加的代码行是if用于测试值是否为的实例的语句Error。如果由于某种原因被捕获,那肯定是Error的instance(我们的代码确保了此错误),并且我们的程序可以安全地处理该情况(在上述情况下,我们将返回500作为服务器响应,从而阻止了该程序由于asyncFunction中的错误而导致执行任何危险代码)。

我故意将其写成两行,以突出这一事实:它可以简洁地编写,并避免使用try/ catch块,许多人不喜欢阅读(我自己就是其中之一)。

如果您对阅读try/ catch块很感兴趣,那么恭喜您。我只是发现它使代码看起来很混乱。那好吧。¯\_(?)_/¯


Jas*_*ing 6

异步/等待和错误处理初学者的实用答案

您不能在未使用async声明或未承诺的函数之外使用await语法。

async function myAsyncFunction() {
  // code
}
Run Code Online (Sandbox Code Playgroud)

要么

const myPromiseFunction = () => new Promise((resolve, reject) => {
    // code
})
Run Code Online (Sandbox Code Playgroud)

因此,最终,您必须使用旧的Promise方法来使用声明为异步的函数

myAsyncFunction().then(() => console.log('here'));
Run Code Online (Sandbox Code Playgroud)

因为两者都是承诺。

我们实际处理错误,如您在使用 - 捕捉方式,你必须构建你的异步函数是这样的...

async function getUser(username) {
  return await db.users.get({ username });
}
Run Code Online (Sandbox Code Playgroud)

那么您可以在异步方法之外像普通的Promise一样使用它...

getUser()
.then(user => console.log(user))
.catch(err => console.error(err));
Run Code Online (Sandbox Code Playgroud)

或者您猜对了,可以在使用await的异步函数中使用它。

async function getJoffery() {
  return await getUser('joffery');
}
Run Code Online (Sandbox Code Playgroud)