while(true)循环中的承诺/等待承诺解决
Promises in while(true) loop / waiting for promise to resolve
我想用node.js写一个小的worker应用。
该应用程序将从AWS-SQS读取数据,以某种方式处理数据,并将其输出到另一个AWS-SQS。到目前为止,我已经写了:
while(true){
readFromQueue()
.then(transform)
.then(writeToQueue);
}
function transform(data) {
console.log("> transforming...");
//transformation logic
return data;
}
//TODO: need to remove message from queue after read!
function readFromQueue() {
// var params = {
// QueueUrl: 'STRING_VALUE',
// WaitTimeSeconds: 2
// };
// return new Promise(function(resolve, reject) {
// sqs.receiveMessage(params, function(err, data) {
// if (err) reject(err);
// else resolve(data);
// });
// });
return new Promise(function(resolve, reject) {
console.log("> reading from queue...");
resolve({ data : "world" });
});
}
function writeToQueue(data) {
// var params = {
// MessageBody: data,
// QueueUrl: 'STRING_VALUE',
// };
// sqs.sendMessage(params, function(err, data) {
// if (err) console.log(err, err.stack);
// else console.log(data);
// });
console.log("> writing to queue...");
console.log(">> " + data);
}
正如你所看到的,一切都是为AWS设置的,但是当我暂时在本地运行它时,我只会在里面有一些模拟的东西,直到我真正得到我的转换逻辑测试等等…
我的问题是:
- AWS-SQS API是异步的,它需要一个回调。我用promise包装了它,因为比起回调,我更喜欢promise。然而,我想知道我是否应该阻止它并使其同步而不是异步(原因如下,但可能是无关的)。
- 当我运行这个,我只能看到"读取队列.."输出,它几乎就像"转换"answers"writeToQueue"没有执行… 然而,如果我注释掉while循环(这样脚本只运行一次),我可以看到所有3个步骤的输出。
我做错了什么吗?我可以理解,因为承诺是异步的,我的while循环会疯狂地创建成千上万个承诺,所以这让我很担心……尽管如此,我还是想在之前的read->transform->write操作完成后启动另一个循环。这里还有什么我应该用的句型吗?或者只是阻塞并等待readFromQueue结束…
——编辑——
如果没有使用while(true):
readFromQueue()
.then(transform)
.then(writeToQueue);
我也明白,因为while(true)正在执行,它实际上会阻塞线程,因此承诺没有解决。那有什么办法吗?
我又回到了我的setInterval
方式。我知道你说过,读取队列必须在写入完成后立即启动,但如果你问我,10ms的延迟并不算多。
function someFunc(){
if(readingQueue) return;
readingQueue = true;
return readFromQueue()
.then(transform)
.then(writeToQueue)
.catch(someErrorHandler)
.then(function(){
readingQueue=false;
})
}
var readingQueue = false;
setInterval(someFunc, 10);
而不是:
while(true){
readFromQueue()
.then(transform)
.then(writeToQueue);
}
你不能使用递归函数吗?像这样:
function getData(){
return readFromQueue()
.then(transform)
.then(function(data){
writeToQueue(data);
getData();
});
}
getData(); //Just to get it starting.
在评估了这里的所有答案后,我尝试了deasync,它做得很好:)
尽管如此,我还是决定使用上面的mido22答案,因为我不想要一个干扰节点事件循环的插件。
我也遇到了类似的问题(参见setTimeout问题试图等待async的执行)。
我已经学会了在javascript中避免的同步模式的教训,所以我认为你的代码可以用类似的东西重写:
function queueLooping(loopExitConditionPromise) {
var blockingGuard = { done: false };
loopExitConditionPromise.then(function () {
blockingGuard.done = true;
});
return loopingSequence;
var loopingSequence = function() {
readFromQueue()
.then(transform)
.then(writeToQueue);
if(!blockingGuard.done)
loopingSequence();
else
return;
};
var readFromQueue = function () {
console.log("> reading from queue...");
// ...
}
var transform = function (data) {
console.log("> transforming...");
// ...
}
var writeToQueue = function (data) {
console.log("> writing to queue...");
// ...
}
}
相关文章:
- 等待循环调用的所有承诺完成
- RxJS等待承诺解决
- 余烬后渲染不等待承诺
- 如何在恢复函数之前等待 JavaScript 承诺解析
- 和Mocha一起等待未兑现的承诺
- 等待承诺
- 在节点中,使用Q,使两个函数并行工作,但只等待第一个函数实现其承诺
- nodeJS 等待无法承诺的事件
- 如何构建一个在上一个 ajax 承诺解析后等待一段时间的 rx 轮询器
- socket.io - 套接字等待承诺
- 为什么 .then() 不等待承诺
- 使用 jQuery 承诺等待转换
- 承诺.resolve 是否等待传递的承诺实现
- 节点和异步/等待,承诺...哪种解决方案最好
- 让承诺等待回拨
- 异步/等待捕获被拒绝的承诺
- Javascript/Angularjs :等待承诺实现,然后再进入foreach Loop中的下一次迭代
- 道场承诺一切 - 但这等待所有承诺的回归
- while(true)循环中的承诺/等待承诺解决
- Javascript承诺等待AccessToken值