This topic created in 4420 days ago, the information mentioned may be changed or developed.
有个需求是发送消息后等待消息,如果超时后,再次发送,直到超时时间超过一定值,如果期间有收到消息,则算成功。
我用q实现promise,但是有点费劲,代码又变成了嵌套的了。
如下:
Q.timeout(send(msg),timeout1)
.then(function(rsp){
// here is fulfilled
)
.catch(function(err)) {
if (err.code==='ETIMEOUT') {
Q.timeout(send(msg),timeout2).then()... // md,这里又来了
}
else {
// here is rejected
}
}
换言之,就是有若干个promise,顺序执行,如果成功了则fulfilled,如果失败了执行下一个,
直到promise都完成。
有没有好的方法,是不是要为Q添加一个Q.once()函数啊?
7 replies • 2014-06-09 13:34:27 +08:00
 |
|
2
andyhu Jun 6, 2014
刚又看了下,觉得bluebird retry文档里的例子应该可以解决楼主的问题。 bluebird可以直接用Promise.promisifyAll来把一个模块所有的函数都变为async的,挺方便,功能强大,并且执行效率超过callback机制的async,可谓promise神器
|
 |
|
3
andyhu Jun 6, 2014
更正,是bluebird *timeout
|
 |
|
4
bolasblack Jun 6, 2014
Q.timeout(send(msg),timeout1).then(function(rsp){ // here is fulfilled }) .catch(function(err)) { if (err.code==='ETIMEOUT') { return Q.timeout(send(msg),timeout2) // 你在这里可以直接 return } else { return Q.reject(err) // 如果返回的是被 reject 的 promise ,那么是不会走到下面的 .then 里去的 } }) .then(function(result) { // 在 catch 里 return 的 promise 如果成功了会走到这里 }) .catch(function(err) { // 在 catch 里 return 的 promise 如果失败了会走到这里 })
|
 |
|
5
ryanking8215 Jun 6, 2014
你好,问题就在这里,如果要发送N次,我就要在代码里写N次的Q.timeout(send(msg))。
现在我解决这个问题了,用递归。
一开始思路错了,想着让Q来解决问题,现在碰到超时,就用递归再调用send(msg)就好了,控制递归的结束条件,恩,如下所示:
function send(msg,timeout,defer){ if (timeout>4000) { defer.reject(new Error("Timeout")) return } // 如果超时了,就继续发送 var id = setTimeout(function({ self.send(msg,timeout*2,defer) // 超时后send again }),timeout)
// 以下是发送和接收消息,要么defer.resolve(),要么defer.resolve() }
function sendMsg(msg) { var defer = Q.defer() this.send(msg,500,defer) return defer.promise }
|
 |
|
7
rekey Jun 9, 2014
还是 ES6 好玩啊。。。
|