如何同步2个或更多异步请求的数据并使用解析的数据发送响应?

时间:2017-08-27 11:55:50

标签: javascript node.js

通过最简单的例子,让我们说他们是2个或更多需要通过发出HTTP请求来提交数据的人,其中一个人提交的数据必须等待其他人发送的其他数据到服务器以便解析。这是我想在Node.js中完成的图像:

enter image description here

当解析数据时,需要将其作为对每个人的回复发回。问题是我坚持实现这个任务(我使用http模块,长轮询,后来我将使用websocket),问题在于回调本质,我尝试使用脏方法,如制作一个数组填写,直到每个人都提交并在setInterval函数的帮助下检查,无论何时解析数据等等。

有没有更清洁,更简洁的方法来实现这些任务?

3 个答案:

答案 0 :(得分:2)

我会给这个过程一个唯一的id(两个客户都知道),然后将相关数据存储在数据库中或直接存储在服务器RAM中。有待处理的请求(请求 - 等待)对服务器来说是不好的,因为它必须保持越来越多的开放连接,并且对于客户端来说是不好的,因为他看到旋转的圈子而不知道发生了什么。我宁愿做以下事情:

Drawable

伪实现看起来像这样:

1. client sends request with data
      2. data gets stored, a *please wait* is returned
3. the page reloads all two seconds
      4. if all the datas there, return the data
      5. if not, return *please wait* and goto 3

答案 1 :(得分:1)

目前最简单的方法是使用Promise.all

function firstAsyncRequest() {
  return new Promise((resolve, reject) => {
    // do your async call and then resolve();
    // or reject() if any error;
  });
}


function secondAsyncRequest() {
  return new Promise((resolve, reject) => {
    // do your async call and then resolve();
    // or reject() if any error;
  });
}

Promise.all([firstAsyncRequest, secondAsyncRequest])
  .then(arrayOfResults => {
      //do your logic
  })
  .catch(err => {
      //catch your error
  })

如果您使用回调,最简单的方法是使用async模块,然后使用async.parallel

async.parallel([
    function(callback) {
        setTimeout(function() {
            callback(null, 'one');
        }, 200);
    },
    function(callback) {
        setTimeout(function() {
            callback(null, 'two');
        }, 100);
    }
],
// optional callback
function(err, results) {
    // the results array will equal ['one','two'] even though
    // the second function had a shorter timeout.
});

答案 2 :(得分:0)

正如我在评论promise.all()中所提到的那样没问题,但是一旦其中一个被拒绝,你就无法控制解决承诺。

相反,您可以使用.reduce()对您的承诺进行排序,并且您可以更好地控制已解决和被拒绝的承诺。

var pr1 = new Promise((v,x) => setTimeout(_ => Math.random() > 0.2 ? v("promise 1 resolved value") : x("Promise 1 rejected"),150)),
    pr2 = new Promise((v,x) => setTimeout(_ => Math.random() > 0.2 ? v("promise 2 resolved value") : x("Promise 2 rejected"),120)),
    pr3 = new Promise((v,x) => setTimeout(_ => Math.random() > 0.2 ? v("promise 3 resolved value") : x("Promise 3 rejected"),60)),
    pr4 = new Promise((v,x) => setTimeout(_ => Math.random() > 0.2 ? v("promise 4 resolved value") : x("Promise 4 rejected"),220)),
    pr5 = new Promise((v,x) => setTimeout(_ => Math.random() > 0.2 ? v("promise 5 resolved value") : x("Promise 5 rejected"),180));

[pr1,pr2,pr3,pr4,pr5].reduce((p,c) => p.then(v => (console.log(`doing something with ${v} and will proceed with the next`),c),
                                             x => (console.log(`Error ${x} however i will proceed with the next`),c)))
                     .then(v => console.log(`finally doing something with ${v}`),
                           x => console.log(`Error ${x} received`));