JavaScript使用Promise/async/await异常:无法正确打印用户角色信息
问题原因
setTimeout本身不返回 Promise,await setTimeout()不会等待定时器执行,只会直接拿到定时器的数字ID作为loginUser的返回值,且定时器回调内部的return仅作用于回调函数本身,外层async函数无法接收该返回值。- 逻辑异常时你直接返回了
Error实例而非抛出错误,不会触发 Promise 的catch分支,错误实例会作为正常值传入后续回调,导致访问name、role属性时得到 undefined。 - 直接写
.then(userStorage.getRoles)会导致getRoles执行时this指向丢失,即使当前逻辑未用到this,也是异步链式调用的常见错误写法。
修复代码
class UserStorage { // 手动封装Promise包裹定时器异步逻辑 loginUser(id, pw) { return new Promise((resolve, reject) => { setTimeout(() => { if ( (id === "ellie" && pw === "dream") || (id === "coder" && pw === "academy") ) { resolve(id); } else { // 异常直接reject抛出,触发catch分支 reject(new Error("not found user info")); } }, 1000); }) } async getRoles(user) { if (user === "ellie") { return { name: "ellie", role: "admin" }; } else { // 异常直接抛出,不要返回Error实例 throw new Error("no access"); } } } const userStorage = new UserStorage(); const id = prompt("wowSans"); const password = prompt("pw"); // 链式调用写法 userStorage .loginUser(id, password) // 用箭头函数包裹保证this指向正确,同时接收上游返回的user参数 .then(user => userStorage.getRoles(user)) .then(value => console.log(`Hi ${value.name}! Your Role is ${value.role}!`)) .catch(console.log);
可选async/await调用写法
如果更习惯用async/await的同步写法,可替换调用部分逻辑:
(async () => { try { const user = await userStorage.loginUser(id, password); const roleInfo = await userStorage.getRoles(user); console.log(`Hi ${roleInfo.name}! Your Role is ${roleInfo.role}!`); } catch (err) { console.log(err); } })()
内容的提问来源于stack exchange,提问作者StackMinsung0809
相关产品推荐
相关产品推荐

