簡體   English   中英

如何在 angular Z3E882BF1F60486B8F3568227E7F2F4 中進行嵌套 javascript 庫 promise 回調

[英]How to do a nested javascript library promise callback inside angular rxjs subscribe call

每當發生錯誤時,我都有一個要求,我需要收集基本錯誤跟蹤、IP 地址和屏幕截圖。

對於Ip地址,我使用這個API來獲取IP地址。 getIp:'http://api.ipify.org/?format=json'。 對於使用 Html2 Canvas:library:https://github.com/niklasvh/html2canvas/issues/2282 的屏幕截圖。

這是發生錯誤時觸發的方法。

我添加了等待,但它沒有等待回調的響應,它將在回調執行發生之前返回。

最初調用

getIP(response:any)
  {
// call 1
    this.getIPAddress().subscribe(async(res:any)=>{ 
    this.ipAddress = res.ip;  
// get an ip once ip recieved call another function


    let errorRequest =  await this.logError(response); call 2
// another service call
    this.logErrorRequest(errorRequest); //  send another service call to server to store the error
    });

    return  errorDetails;
  } 

第二次調用..在這種方法中格式化請求。 這里的截圖,我需要調用 javascript 庫 html2canvas。 等待這個.getScreenShot()

// 這里的問題是該方法將在從 promise 調用獲得響應之前返回響應。

async logError(response:any):ErrorRequest{
    error={
        ExceptionMessage:response.message,
        ipAddress:this.ipAddress,
        screenShot:await this.getScreenShot()    // next call 3.
    };
   
    return error;
}

// promise 回調

async getScreenShot() {
    this.zone.runOutsideAngular(() => {
// call 4
      html2canvas(document.querySelector("#capture")).then(canvas => {
      canvas.toBlob(function(blob){
                let link = document.createElement("a");
                link.download = "image.png";
                link.href = URL.createObjectURL(blob);
                link.click();
                let screenShot = blob; 
                 this.screenShot = blob;

            },'image/png');

   
         //your code
      })   

    });

你沒有從你的getScreenShot()返回任何東西,除了Promise<void>但這只是因為async 感覺前兩個調用並不相互依賴,因此您可以並行執行它們:

這意味着,要解決您的問題,您需要重構您的getScreenShot()方法:

getScreenShot() {
  return this.zone.runOutsideAngular(async () => {
    const canvas = await html2canvas(document.getElementById("capture"));

    return new Promise(
      (resolve) => canvas.toBlob((blob) => resolve(blob), 'image/png')
    );
  });
}

簡而言之,返回this.zone調用,等待html2canvas調用,創建一個新的 promise 並在您的解析中返回它。 另外,不要使用function關鍵字,因為這會弄亂this上下文。


需要重構代碼的較長修復看起來像這樣:

logError(response: { message: string }): void {
  forkJoin([
    this.getIPAddress(),
    this.getScreenShot()
  ]).pipe(
    concatMap(([ { ip }, screenshot ]) => this.logErrorRequest({
      ExceptionMessage: response.message,
      ipAddress: ip,
      screenshot
    }))
  ).subscribe({
    next: () => console.log('error logged'),
    error: () => console.log('make sure to catch this to prevent loop!')
  });
}

這顯然會使用重構的getScreenShot方法。 如您所見,這更加清晰,並且避免了使用隨機this分配。 這是一個不錯的 stream,就像 rxjs 想要的東西一樣。

還要確保您以某種方式對錯誤記錄進行去抖動/分組,以防止記錄錯誤的泛濫或無限循環。 相信我,它會發生:D

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM