2015-06-29 68 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