2015-06-29 23 views
0

我與Facebook的圖形API,這往往會返回一個「未知錯誤」的消息,我覺得如果我幾秒鐘後重試後它的工作原理沒有問題的工作。如何組織一個遞歸調用的承諾

此代碼將爲postAsync一個電話,在收到成功應答,將解決與新的承諾,否則會增加的嘗試計數器,並再次調用該函數。

function guaranteedPost(endpointId, wallPost, attempts){ 
    attempts = attempts || 0 
    ++attempts 
    return graph.postAsync(endpointId + '/feed', wallPost).then(function(response){ 
    return new Promise.resolve(response) 
    }).catch(function(error){ 
    setTimeout(function(){  
     console.log(attempts) 
     console.log(error) 
     if(attempts == 2){ 
     return Promise.reject('Too many attempts') 
     } 
     else{ 
     return guaranteedPost(endpointId, wallPost, attempts) 
     } 
    }, 5000) 

    }); 
} 

guaranteedPost(endpointId, wallPost, 0).then(function(value){ 
    console.log(value) 
}) 
.catch(function(error){ 
    console.log(error) 
}) 

我希望能夠使用的代碼,例如,在那裏我稱之爲guaranteedPost,並登錄到控制檯或者響應,或單一的「嘗試次數過多」的錯誤消息。但是,在現階段,我收到我的輸出:

undefined 
Unhandled rejection Error: Too many attempts 

因此,不確定的第一個電話的回報和第二個電話,其中有沒有錯誤處理,炸燬。

另外,我想這可以訪問之前定義的變量更大的功能範圍內使用,因此,我不希望拔出錯誤和成功處理成自己的功能。

我不禁覺得我很接近,但是這是一個完整的重構或兩個後,我還是不太釘子它。我如何正確設計這個?

+0

遞歸你必須從'guaranteedPost' – laggingreflex

+0

對不起調用'guaranteedPost',我剛剛改名功能張貼在S.O.更新的代碼實際上反映了我正在使用的內容。 – Antoine

回答

1

將您的超時邏輯分成實際承諾,並返回。通過這樣做setTimeout,你會發現錯誤並且什麼也不返回,那麼排隊一個新的請求,沒有任何東西可以解決它的失敗。承諾都是關於鏈接。

function delay(ms){ 
    return new Promise(function(resolve){ 
    setTimeout(resolve, ms); 
    }); 
} 

function guaranteedPost(endpointId, wallPost, attempts){ 
    attempts = attempts || 0 
    ++attempts 
    return graph.postAsync(endpointId + '/feed', wallPost).then(function(response){ 
    return new Promise.resolve(response) 
    }).catch(function(error){ 

    // Return a promise that waits a little bit, then tries again. 
    return delay(5000).then(function(){  
     console.log(attempts) 
     console.log(error) 
     if(attempts == 2){ 
     return Promise.reject('Too many attempts') 
     } 
     else{ 
     return guaranteedPost(endpointId, wallPost, attempts) 
     } 
    }) 

    }); 
} 

我還簡化了這個代碼了一點:

function delay(ms){ 
    return new Promise(function(resolve){ 
    setTimeout(resolve, ms); 
    }); 
} 


function guaranteedPost(endpointId, wallPost, attempts){ 
    return graph.postAsync(endpointId + '/feed', wallPost) 
    .catch(function(error){ 
     if (attempts === 2) throw new Error('Too many attempts'); 

     // Return a promise that waits a little bit, then tries again. 
     return delay(5000).then(function(){ 
     return guaranteedPost(endpointId, wallPost, (attempts | 0) + 1); 
     }) 
    }); 
} 
+0

感謝您的回覆,我能夠得到它的工作。對我而言,缺失的部分是將「解決方案」傳遞給Promise的能力,這保證只返回一個值。我閱讀了Promise.resolve的MDN描述,但沒有在其中找到任何信息。再次感謝! – Antoine

+0

另外,我使用藍鳥作爲圖書館。我很確定有一種延遲方法可用,閱讀文檔並取代setTimeout是一個更好的主意嗎? – Antoine

+1

完全是,只是不確定你在使用什麼庫,所以我去了ES6的標準方法。 – loganfsmyth