2017-08-01 27 views
2

我的移動應用程序連續上傳幾個文件到服務器,通常從連接強度有問題的偏遠地區。出於這個原因,我想嘗試發送文件。我還想繼續嘗試下一個失敗的事件,並在導出結束時顯示所有錯誤消息(即「上傳10個文件,3個失敗...」)承諾重試,直到成功/失敗與Typescript

但是,我無法用promise來計算遞歸重試模式。這是我到目前爲止:

當我在服務器上引發異常,我會看到「失敗3次!!!」錯誤消息,但調用承諾不能解決導出的其餘部分繼續前進。我相信這是因爲我創建了嵌套承諾(即每次重試都創建一個新承諾)。如何在3次重試後解決原始承諾?

謝謝!

+1

你需要做的事情在'this.sendFile返回的承諾(參數,可以--retries)' 試試這個: 'this.sendFiles(參數,可以--retries).resolve(解析,拒絕)' – Antony

+0

我需要重試Promise,所以我查看了那裏的內容,然後發現TypeScript沒有真正的存在,所以我推出了自己的。反饋歡迎。 https://npmjs.com/package/retry-promise-typescript –

回答

1

這裏是結束了工作:

sendFile(params, retries = 3, promise = null){ 
    console.log("SENDING FILE: ", retries, "attempts remaining", params) 

    if(retries > 0){ 
     return this._sendFile(params) 
     .then(()=>{ 
     // Upload Success 
     console.log("Upload Success!") 
     return Promise.resolve(true) 
     }) 
     .catch((err)=>{ 
     console.log("Upload Fail", err) 

     this.exportStatus.retries++ 

     return this.sendFile(params, --retries) // <-- The important part 
     }) 
    }else{ 
     console.log("Failed 3 times!!!") 

     this.exportStatus.errors.push({ 
     message:"A file failed to upload after 3 attempts.", 
     params: params 
     }) 

     return Promise.resolve(false) 

    } 

    } 
2

你可以實現一個包裝器Promise()自動鏈重試給你,讓你與你需要的任何邏輯重構你的代碼,而不是同時擔心處理重試邏輯。您的使用可能是這個樣子:

sendFile(params, retries = 3) { 
    return Promise.retry(retries, (resolve, reject) => { 
    this._sendFile(params).then(resolve, reject) 
    }) 
} 

下面是你如何能實現Promise.retry()

Object.defineProperty(Promise, 'retry', { 
 
    configurable: true, 
 
    writable: true, 
 
    value: function retry (retries, executor) { 
 
    console.log(`${retries} retries left!`) 
 

 
    if (typeof retries !== 'number') { 
 
     throw new TypeError('retries is not a number') 
 
    } 
 

 
    const promise = new Promise(executor) 
 

 
    if (retries > 0) { 
 
     return promise.catch(error => Promise.retry(--retries, executor)) 
 
    } 
 

 
    return promise 
 
    } 
 
}) 
 

 
Promise.retry(100, (resolve, reject) => { 
 
    // your sendFile core logic with proper 
 
    // calls to resolve and reject goes here 
 
    const rand = Math.random() 
 

 
    console.log(rand) 
 

 
    if (rand < 0.1) resolve(rand) 
 
    else reject(rand) 
 
}).then(
 
    value => console.log(`resolved: ${value}`), 
 
    error => console.log(`rejected: ${error}`) 
 
)

如果你是延伸的原生對象不舒服(這將是正確的方式來做這件事,因爲它是一個可配置的,不可枚舉的和可寫的屬性),你可以將它作爲一個靜態函數來實現:

function retry (retries, executor) { 
    console.log(`${retries} retries left!`) 

    if (typeof retries !== 'number') { 
    throw new TypeError('retries is not a number') 
    } 

    const promise = new Promise(executor) 

    if (retries > 0) { 
    return promise.catch(error => retry(--retries, executor)) 
    } 

    return promise 
}