正确使用 Promise.resolve().then() 错误:未捕获(在承诺中):TypeError:无法读取属性
Posted
技术标签:
【中文标题】正确使用 Promise.resolve().then() 错误:未捕获(在承诺中):TypeError:无法读取属性【英文标题】:Using Promise.resolve().then() correctly Error: Uncaught (in promise): TypeError: Cannot read property 【发布时间】:2020-04-29 18:11:43 【问题描述】:我有这个代码:
export class Page
constructor(public modalController: ModalController)
private async openModal(value)
const modal = await this.modalController.create(
component: AnotherPage,
componentProps:
"paramID": 123,
"paramTitle": "Test Title",
"takenPhoto": "null"
);
return await modal.present();
public async takePicture()
this.openModel(null); // here's OK
Promise.resolve(this.someMethod()).then(this.openModal); // ERROR!!
在takePicture
方法上,我想在执行Promise.resolve
之后打开一个模式。在第一次执行时一切正常,但在第二次执行时出现错误。
错误:
ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'modalController' of undefined
TypeError: Cannot read property 'modalController' of undefined
at tab2.page.ts:25
at Generator.next (<anonymous>)
at tslib.es6.js:73
at new ZoneAwarePromise (zone-evergreen.js:876)
at Module.__awaiter (tslib.es6.js:69)
at openModal (tab2.page.ts:22)
at ZoneDelegate.invoke (zone-evergreen.js:359)
at Object.onInvoke (core.js:34201)
at ZoneDelegate.invoke (zone-evergreen.js:358)
at Zone.run (zone-evergreen.js:124)
at resolvePromise (zone-evergreen.js:797)
at resolvePromise (zone-evergreen.js:754)
at zone-evergreen.js:858
at ZoneDelegate.invokeTask (zone-evergreen.js:391)
at Object.onInvokeTask (core.js:34182)
at ZoneDelegate.invokeTask (zone-evergreen.js:390)
at Zone.runTask (zone-evergreen.js:168)
at drainMicroTaskQueue (zone-evergreen.js:559)
【问题讨论】:
这能回答你的问题吗? How to access the correct `this` inside a callback? 既然 takePicture 方法是异步的,你不能先等待 this.someMethod 再继续执行 this.openModal 吗? @tlm 我不这样,因为 this.someMethod() 返回一个 Promise 提供您创建Page
实例的方式。
【参考方案1】:
export class Page
constructor(public modalController: ModalController)
private async openModal(value)
const modal = await this.modalController.create(
component: AnotherPage,
componentProps:
"paramID": 123,
"paramTitle": "Test Title",
"takenPhoto": "null"
);
return modal.present();
public async takePicture()
await this.openModel(null); // Need to await a promise
const data = await this.someMethod()
await this.openModal(data);
【讨论】:
【参考方案2】:为什么会发生错误? 这是因为如果您想在一个隐式函数调用中调用“this”,您必须将这个调用绑定到“this”状态。看看吧:
之前:
public async takePicture()
this.openModel(null); // here's OK
Promise.resolve(this.someMethod()).then(this.openModal); // ERROR!!
之后:
public async takePicture()
this.openModel(null); // here's OK
Promise.resolve(this.someMethod()).then(this.openModal.bind(this)); // JUST FINE :)
现在隐式调用将接收到 this 状态以在此处正确使用:
await this.modalController.create(...
Se precisar de ajuda em pt-BR pod mandar msg :)
【讨论】:
【参考方案3】:根据@VLAZ 所说的(我建议阅读他提供的链接),您假设this
在 openModal() 函数的上下文中引用了类的上下文。由于this
的值仅取决于函数的“调用方式”,因此this.modalController
上this
的出现尚未绑定到上下文,因此this
变为未定义,这就是原因你得到了错误。
您可以在调用函数之前将this
设置为类的上下文。以下是一些方法:
1 - 在构造函数中绑定this
constructor(public modalController: ModalController)
this.openModal = this.openModal.bind(this);
2 - 使用箭头函数自动将this
绑定到类的上下文(父上下文)。
openModal = async (value) =>
const modal = await this.modalController.create(
component: AnotherPage,
componentProps:
"paramID": 123,
"paramTitle": "Test Title",
"takenPhoto": "null"
);
return modal.present();
我认为还有其他方法可以做到这一点,但这些方法已被广泛接受。 希望对您有所帮助!
【讨论】:
以上是关于正确使用 Promise.resolve().then() 错误:未捕获(在承诺中):TypeError:无法读取属性的主要内容,如果未能解决你的问题,请参考以下文章
Promise.resolve 与新的 Promise(resolve)
Promise.resolve()与new Promise(r =; r(v))