while(true) 循环中的承诺/等待承诺解决

Dan*_*zyk 3 javascript amazon-web-services node.js promise

我想在 node.js 中编写一个小型工作应用程序。
该应用程序将从 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);
}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,一切都为 AWS 设置好了,但是当我暂时在本地运行它时,我只会在里面放一些模拟的东西,直到我真正测试我的转换逻辑等等......
我遇到的问题是:

  • AWS-SQS API 是异步的,它需要一个回调。我用承诺包装它,因为我更喜欢承诺而不是回调。尽管如此,我想知道我是否应该阻止它并使其同步而不是异步(原因如下,但可能无关)。
  • 当我运行它时,我只能看到“从队列中读取..”输出,就好像没有执行“转换”和“写入队列”一样......
  • 但是,如果我注释掉 while 循环(因此脚本只运行一次),我可以看到所有 3 个步骤的输出。

所以我做错了什么吗?我可以理解,由于 Promise 是异步的,我的 while 循环会发疯并创建数千个,所以这让我担心......不过我想在上一个 read->transform->write 完成后启动另一个循环。我应该在这里使用其他模式吗?或者只是阻塞并等待 readFromQueue 结束......

--EDIT--
如果不包含在 while(true) 中,它会执行所有内容:

readFromQueue()
        .then(transform)
        .then(writeToQueue);
Run Code Online (Sandbox Code Playgroud)

我也明白,由于 while(true) 正在执行,它本质上会阻塞线程,因此承诺没有得到解决。那么有没有办法解决呢?

mid*_*ido 5

我又回到了我的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);
Run Code Online (Sandbox Code Playgroud)