Uncaught (in promise) undefined - Vue-router
Posted
技术标签:
【中文标题】Uncaught (in promise) undefined - Vue-router【英文标题】: 【发布时间】:2019-12-20 22:35:39 【问题描述】:我遇到了一个非常奇怪的问题,如果权限受限的用户尝试登录我的网络应用程序,他们会看到以下错误:
Uncaught (in promise) undefined
但这不会发生在拥有最大权限的用户身上。
我认为问题是由重新路由引起的。如果用户没有 page_access 1,它会路由到 /holidays。另一个奇怪的是,这个错误只会出现一次,那是用户第一次登录的时候。如果页面被刷新或者用户导航到其他页面,它就不会出现。
router.js
Vue.use(Router)
const router = new Router(
routes: [
path: '/',
name: 'dashboard',
component: Dashboard,
beforeEnter(to, from, next)
if(localStorage.token)
if(localStorage.page_access.indexOf('1') != -1 && localStorage.page_access != null)
next('/holidays');
else
next();
else
next('/login');
,
path: '/holidays',
name: 'holidays',
component: Holidays,
beforeEnter(to, from, next)
if(localStorage.token)
next();
else
next('/login');
,
],
mode: 'history'
)
router.beforeResolve((to, from, next) =>
if(localStorage.token && from.name != 'login' && to.name != 'login')
store.dispatch('autoLogin')
.then(response =>
store.dispatch('getNavigation');
next();
)
.catch(err =>
console.log(err);
);
else if(from.name && !localStorage.token)
router.go('/login');
else
next();
);
export default router;
store.js
async autoLogin(commit)
const token = localStorage.getItem('token');
const remember_token = localStorage.getItem('remember_token');
if(!token)
return;
try
const res = await axios(
method: 'post',
data: userId: localStorage.user_id, token: localStorage.remember_token ,
url: 'https://controlapi.totalprocessing.com/api/get-user',
config: headers: 'Content-Type': 'application/x-www-form-urlencoded'
)
.then(response =>
if(response.data.remember_token == remember_token)
commit('authUser', token: token );
return response;
else
localStorage.clear();
return null;
)
.catch(e =>
this.errors.push(e);
return e;
)
return res;
catch(e)
console.log(e);
return e;
getNavigation(commit)
let pageAccess = localStorage.page_access == 'null' ? null : localStorage.page_access;
let subPageAccess = localStorage.sub_page_access == 'null' ? null : localStorage.sub_page_access;
axios(
method: 'post',
data: pageAccess: pageAccess, subPageAccess: subPageAccess ,
url: 'https://controlapi.totalprocessing.com/api/client-get-navigation',
config: headers: 'Content-Type': 'application/x-www-form-urlencoded'
)
.then(response =>
console.log(response.data);
const data = response.data;
const tree = [];
data.reduce(function(a, b, i, r)
// Add the parent nodes
if(a.page_id != b.page_id)
tree.push( page_id: a.page_id,
page_name: a.page_name,
page_path: a.path,
page_icon: a.page_icon
);
// Add the last parent node
if(i+1 == data.length)
tree.push( page_id: b.page_id,
page_name: b.page_name,
page_path: b.path,
page_icon: b.page_icon
);
// Add the child nodes to the parent nodes
data.reduce(function(a, b)
if(a.sub_page_id)
const find = tree.findIndex(f => f.page_id == a.parent_id);
// Add the first child node to parent
if(!("children" in tree[find]))
tree[find].children = [];
tree[find].children.push( page_id: a.sub_page_id,
page_name: a.sub_page_name,
page_path: a.sub_page_path,
page_icon: a.sub_page_icon
);
// Add the remaining child nodes to parent nodes
else
tree[find].children.push( page_id: a.sub_page_id,
page_name: a.sub_page_name,
page_path: a.sub_page_path,
page_icon: a.sub_page_icon
);
return b;
);
return b;
);
commit('authNav',
navigation: tree
);
)
.catch(e =>
this.errors.push(e)
)
【问题讨论】:
你能加入getNavigation
行动
@Dadboz - 我已经完成了那个伙伴。我不认为这是因为当我注释掉该行时,错误仍然存在。
我有同样的问题,但似乎没有什么问题:/
这里相同...我使用了 enso 的答案,甚至调试了“错误”,它只显示“未定义”。所以有一个错误,但它是未定义的?对我来说似乎是一个错误,即使是 3.1.2
【参考方案1】:
我们的问题是一样的。登录页面可以跳转到这个路径,写:
this.$router.push( path: this.redirect || '/' , onComplete => , onAbort => )
错误的写法是:
this. $router. Push (path: this. Redirect | '/')
【讨论】:
【参考方案2】:根据我过去几天的经验,在调用this.$router.push()
的函数中捕获错误至关重要。
我发现有两种方法非常可行:
handleSomething()
this.$router.push().catch((err) =>
throw new Error(`Problem handling something: $err.`);
);
,
和
async handleSomething()
try
await this.$router.push();
catch (err)
throw new Error(`Problem handling something: $err.`);
,
目前,我更喜欢这里的 async/await 技术,因为它具有执行阻塞的性质,但是您应该注意的关键是“未捕获的 promise”错误本身是 javascript 中经常提到的一个已知问题作为“被吞下的承诺”,它是由被拒绝的 Promise 引起的,但“错误”被吞下,因为它没有被正确捕获。也就是说,没有任何代码块可以捕获错误,因此您的应用无法对错误做出任何响应。
这意味着最重要的是不要吞下错误,这意味着您需要在某个地方捕获它。在我的两个示例中,您可以看到错误将通过 catch 块传递。
错误吞咽的次要事实是,错误甚至一开始就被抛出。在我看到这一点的应用程序中,很难调试,但我可以看到错误的性质与路由更改时 Vue 组件的卸载和加载有关。例如,如果您在一个组件中调用 this.$router.push()
,然后该组件在路由更改正在进行时被销毁,那么您可能会看到这样的错误是合理的。
作为此问题的扩展,如果发生路由更改并且结果组件在 Promise 解决之前尝试从 .push()
事件中读取数据,它也可能会抛出此错误。 await
应该通过指示您的应用程序在读取前等待来停止此类错误。
简而言之,调查这两件事:
-
您是否在
this.$router.push()
执行时以某种方式破坏/创建组件?
下一个组件是否可能在路由更改完成之前读取有关路由参数的数据?
如果您发现其中一些可能会发生,请考虑您的数据流,并确保通过驯服异步行为来解决它,而不仅仅是通过抑制错误。在我看来,错误是更大问题的征兆。
在调试期间,将console.log()
s 添加到所有组件的created/mounted
和destroyed
生命周期方法中,以及与路由更改相关的函数中。您应该能够掌握数据的流动方式。
我怀疑此问题的性质源于在飞行中路线更改期间对this.$route.params
的下游使用。添加大量 console.logs 和/或单步调试器。
【讨论】:
奇怪的是,没有 try catch 并且只有 awaitawait this.$router.push('/account')
'Promise must be proper handling' 错误我已经消失了。
这表明$router.push()
返回了一个promise,并且没有等待,您的代码将继续前进,下游代码会尝试在promise 的结果被解析之前读取它。添加await
会延迟下游代码,因此它会读取已解决的promise,而不是in-flight 的promise。【参考方案3】:
在我的例子中,我只需要在router.push
方法中添加一个catch
:
router.push(query: newQueryObj)).catch(e => )
查看related issue了解更多详情。
【讨论】:
【参考方案4】:添加 main.js;
import Router from 'vue-router'
const routerPush = Router.prototype.push
Router.prototype.push = function push(location)
return routerPush.call(this, location).catch(error=> error)
或者; npm i vue-router@3.0 -S
【讨论】:
【参考方案5】:我也遇到了这个问题,将路由器中的 !variable
更改为 variable !==
就可以了。
else if(from.name && !localStorage.token)
router.go('/login');
到
else if(from.name && localStorage.token === '')
router.go('/login');
【讨论】:
对我的情况没有帮助。实际上触发的是它上面的块,而不是 else if,因为这发生在用户第一次登录时。 这对我有帮助,但我不清楚这对我有什么帮助/为什么...以上是关于Uncaught (in promise) undefined - Vue-router的主要内容,如果未能解决你的问题,请参考以下文章
Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0 Promise [重复]
解决Uncaught (in promise) reason的问题
Uncaught (in Promise) DOMException: play() 只能由用户手势启动
解决Uncaught (in promise) reason的问题