【问题标题】:Promise returns undefined value inside ngOnInit in Angular 8 ionic 4Promise 在 Angular 8 ionic 4 的 ngOnInit 中返回未定义的值
【发布时间】:2019-09-25 15:34:03
【问题描述】:

在我的 Ionic 4 angular 8 应用程序中,我使用 chrome 扩展来返回选项卡 URL。我在服务文件中定义的函数中获取选项卡 URL 值,但是当在 ngOnInit() 中调用服务时,我变得未定义。请帮我解决这个问题。

我希望 URL 值显示在ngOnInit()

内部服务文件

async chromeCall() {
    try {          
      const results = await chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
        chrome.tabs.sendMessage(tabs[0].id, { from: 'popup', subject: 'DOMInfo' }, (response) => {
          console.info("Tab ID:", tabs[0].id);
          this.CurrentPgUrl = response.webPgURL;
          console.log(this.CurrentPgUrl);//geting value here
          return this.CurrentPgUrl;
        });
      });
    }
    catch (err) {
      console.log(err);
      console.log("comes to error ");          
    }
  }

内部ngOnit()

 ngOnInit(){
    this.apiService.chromeCall()
    .then(result => {
      this.url=result;
      console.log(this.url)//value undefined
 )};

【问题讨论】:

  • 你的意思是this.CurrentPgUrlundefined 吗?
  • 我建议不要使用function(tabs) {...},而是使用(tabs) => {...}。这是因为function 创建了一个新的作用域,所以this 不再指代相同的东西了。
  • 我不确定这是您遇到的问题,但可能是
  • 是的,我在 ngOnit() 中需要 this.currentPgurl。但现在我越来越不确定
  • 您是否尝试使用粗箭头 (=>) 而不是 function

标签: angular typescript promise ionic4 angular8


【解决方案1】:

chromeCall 必须返回一个承诺 - 或者任何东西,真的,正如它所写的那样,它返回未定义。 chrome.tabs.query 是使用回调配方构建的,而不是承诺配方,所以 awaiting 它不会做任何值得注意的事情。

应该是这样的:

chromeCall() {
    return new Promise(
        (resolve, reject) => chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
// dive into the callback hell here, and on the final line...
            resolve(this.CurrentPgUrl);
        }
// and the appropriate number of closing `}`s

或者,您可以使用承诺这些方法的库。例如,这个看起来可以完成这项工作: https://www.npmjs.com/package/chrome-extension-async

【讨论】:

  • 按预期获取值。谢谢
【解决方案2】:

你可以这样尝试,这里我们使用了一个承诺,所以在从 chrome 标签获得预期结果后,我们正在解决这个承诺,所以你不会得到undefined。希望对你有帮助。

async chromeCall() {
    try {

      const results = await chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
   return new Promise(resolve => {
          chrome.tabs.sendMessage(tabs[0].id, { from: 'popup', subject: 'DOMInfo' }, 
          (response) => {
             console.info("Tab ID:", tabs[0].id);
             this.CurrentPgUrl = response.webPgURL;
             console.log(this.CurrentPgUrl);//geting value here
             resolve (this.CurrentPgUrl);
        });
      });
   });     
    }
    catch (err) {
      console.log(err);
      console.log("comes to error ");

    }
  }

ngOnInit

 ngOnInit(){
    this.apiService.chromeCall()
    .then(result =>{
    this.url=result;
    console.log(this.url)//value undefined
    )};

【讨论】:

  • 我仍然在 ngOnInit() 中未定义。
  • @SRI 你有没有尝试在function(tabs) { ... } 之前写await
【解决方案3】:

选项 1:您可以为 ngOnInit 方法放置异步等待概念,就像这样,

async ngOnInit(){
    let serviceResponse = await this.apiService.chromeCall();
     if(serviceResponse){
       this.url=result;
     }
 }

选项2:可以在side then call back方法中添加if条件,就是这样,

ngOnInit(){
    console.log('Loading start')
    this.apiService.chromeCall()
    .then(result =>{
        if(result){
            this.url=result;
            console.log('Loading ends')
            console.log(this.url)
            return
        }
        console.log('Loading ends')
    ).catch(err) => {
        console.log('Loading ends', err);
    }
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-31
    • 2020-03-25
    • 2019-01-10
    • 2019-10-19
    • 1970-01-01
    • 2020-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多