如何在不知道请求数量的情况下链接Javascript ajax请求。 (的NodeJS)

时间:2017-08-17 09:02:39

标签: javascript node.js ajax

让我说我需要POST item1然后等待响应然后POST item2等等,但我不知道项目的数量,我只知道他们需要按顺序。

for(item in array){
  request({
    uri: 'http://some.url/',
    method: 'POST',
    data: item
  }, function(clbck){
    <request with data item2 and so on>
  })
}

等等直到请求(n)没有完成。

如何在不知道数量的情况下链接请求?

3 个答案:

答案 0 :(得分:1)

此问题的解决方案是AN AMAZING async / await功能。但我在回调中使用它们,我需要进行回避。

// init a async function
const post_message = async (id, array) => {

    // init loop of requests
    for(let iter = 0; iter<array.length; iter++){

        // lets wait for promise to resolve or reject (no need to return anything)
        await new Promise(function(resolve,reject){
            request({
                uri: 'my_post_url',
                method: 'POST',
                json: {data: my_data}
            },function(error,response,body){
                if(error) {
                    reject('REJECTED')
                } else {
                    resolve('RESOLVED')
                }
            })
        })
    }
}

并且我们可以链接(等待)一个接一个的请求,这里的关键是await在promice上寻找解决或拒绝(然后,捕获),await不关心回调或返回或者尝试/捕捉方法......

答案 1 :(得分:0)

使用回调:

const makeRequest = (item, cb) => request({
  uri: 'http://some.url/',
  method: 'POST',
  data: item
}, cb);

// 1. reverse() so that we can start building the callback chain from the end
// 2. Build up callback chain (starting with no-op function passed in as initial state
//    to reduce) by returning a function which calls makeRequest() with the current item
//    and passes the existing chain of callbacks to be called after that request finishes

const callbackChain = array.reverse().reduce((chain, item) => {
  return () => makeRequest(item, chain);
}, () => {});

callbackChain();


使用promises(需要承诺返回版本的request):

let promise = Promise.resolve();

// You can always attach more .then callbacks to an existing promise
for (let item of array) {
  promise = promise.then(() => request({
    uri: 'http://some.url/',
    method: 'POST',
    data: item
  }));
}

Array#reduce

const promise = array.reduce((promise, item) => {
  return promise.then(() => request({
    uri: 'http://some.url/',
    method: 'POST',
    data: item
  }));
}, Promise.resolve());

答案 2 :(得分:0)

您甚至不需要promises / async-await或其他库:

function do(item) {
    request({
        uri: 'http://some.url/',
        method: 'POST',
        data: item
    }, () => {
        let nextElement = array.shift();
        if (nextElement) {
            do(nextElement);
        }
        else {
            // all done
        }
    });
}

do(array.shift());

或者如果你想让它更清洁,async.eachSeries将是一个很好的解决方案