簡體   English   中英

重試,然后忽略錯誤並獲取源值 rxjs

[英]Retry, then ignore error and get source value rxjs

錯誤或沒有錯誤,我想在重試后進入訂閱成功處理程序。 要進行測試,請注釋掉 setTimeout 行。 這將使 checkforText$ 總是拋出錯誤。 我想忽略最后的錯誤,仍然將編輯器返回給訂閱成功處理程序。

https://codepen.io/Spankid/pen/gOgVZEE

var editor = { innerText: "" }
var editorOpened$ = of(editor) // observe editor object

function checkforText(){
    return new Promise((resolve,reject) => {
        console.log('checking for text',editor)
    
        if (editor.innerText == ""){
            reject('No text');
        } else {
            resolve(editor)
        }
    })
}

var checkForText$ = defer( () => from(checkforText())) // observe text on editor object

// comment out this line out to test
setTimeout( _ => { editor.innerText = 'testing' }, 2000) 

editorOpened$.pipe( 
    switchMap(editor => 
        checkForText$.pipe(
            retryWhen(errors => {
                console.log ('no text found... retrying')
                return errors.pipe( 
                    delay(1000), 
                    take(3),
                )
            }),     
         )
     )  
).subscribe(editor => {
    console.log('FINISH CHECKING', editor)  
}, err => console.log('ERROR ',err))
    

找到文本時的 Output(setTimeout 未注釋掉):

checking for text {innerText: ""}
no text found... retrying
checking for text {innerText: ""}
checking for text {innerText: "testing"}
FINISH CHECKING {innerText: "testing"}

找不到文本時目標 output(注釋掉 setTimeout):

checking for text {innerText: ""}
no text found... retrying
checking for text {innerText: ""}
checking for text {innerText: ""}
checking for text {innerText: ""}
FINISH CHECKING {innerText: ""}

未找到文本時的實際 output(注釋掉 setTimeout):

checking for text {innerText: ""}
no text found... retrying
checking for text {innerText: ""}
checking for text {innerText: ""}
checking for text {innerText: ""}

我嘗試在 retryWhen 之后添加 catchError,希望將其變成訂閱成功處理程序。 但它仍然沒有。 有任何想法嗎?

retryWhen是不可能的。

retryWhen運算符在重試給定嘗試后completes (在這種情況下,由take(3)delay(1000)指定)。 因此,如果在重試期間,您的可觀察源checkForText$沒有發出已解析的 promise 或非錯誤值,則由 checkForText$ 和 retryWhen 組成的管道不會發出任何內容,最終 stream 將完成后重試。

在那之后沒有辦法進入成功處理程序,除非您專門讓 checkForText$ 在重試期間發出一些非錯誤值。

因此,如果您在觀察者中添加一個完整的回調,如下所示,

editorOpened$.pipe( 
    switchMap(editor => 
        checkForText$.pipe(
            retryWhen(errors => {
                console.log ('no text found... retrying')
                return errors.pipe( 
                    delay(1000), 
                    take(3),
                )
            }),     
         )
     )  
).subscribe(editor => {
    console.log('FINISH CHECKING', editor)  
  }, 
  (err) => console.log('ERROR ',err), 
  () => console.log('I'm done!') //The complete handler
);

當您沒有找到帶有 setTimeout 注釋的文本時,您的情況將返回以下 -

checking for text {innerText: ""}
no text found... retrying
checking for text {innerText: ""}
checking for text {innerText: ""}
checking for text {innerText: ""}
I'm done!

但是,您可以使用retry來實現此目的,但我不確定如何僅使用retry來引入延遲。

editorOpened$
  .pipe(
    switchMap(editor =>
      checkForText$.pipe(
        retry(3),
        catchError(errors => of(editor))
      )
    )
  )
  .subscribe(
    editor => {
      console.log("FINISH CHECKING", editor);
    },
    err => console.log("ERROR ", err),
    () => console.log("I'm done!")
  );

這將產生:

checking for text {innerText: ""}
checking for text {innerText: ""}
checking for text {innerText: ""}
checking for text {innerText: ""}
FINISH CHECKING {innerText: ""}
I'm done!

正如上面的帖子所指出的, retryWhen 是不可能的 但是,您可以使用 retry 來實現這一點,方法是確保您的源 observable 處理任何延遲。

editorOpened$
  .pipe(
    mergeMap(editor =>
      checkForText$.pipe(
        retry(3),
        catchError(errors => of(editor))
      )
    )
  )
  .subscribe(
    editor => console.log("Finish", editor);,
    err => console.log("Error", err),
    _ => console.log("Complete")
  );

源可觀察

function checkforText(){
    return new Promise((resolve,reject) => {
        console.log('checking for text', editor)
        if (editor.innerText == ""){
            setTimeout(_=> reject('No text'), 500); // reject after half a second
        } else {
            resolve(editor)
        }
    })
}

var checkForText$ = defer(_=> from(checkforText())) 

暫無
暫無

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

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