2017-08-17 60 views
1

可以說我需要POST項目1,然後等待一個響應,然後POST項目2等,但我不知道項目的數量,我只知道他們需要按順序。如何在不知道請求數的情況下鏈接Javascript ajax請求。 (Nodejs)

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

等等直到請求(n)不完成。

如何在不知道數量的情況下鏈接請求?

+0

一個選項:承諾。這裏是一個幫手方法:https://www.npmjs.com/package/promise-reduce – undefined

+0

但是如何鏈接它們? @Ram – F1ks3r

+0

這個藍鳥文檔頁面有一些例子:http://bluebirdjs.com/docs/api/promise.reduce.html請注意,reducer函數應該返回一個promise,如果請求不應該順序執行,你也可以使用'Promise.each'幫手。 – undefined

回答

1

該問題的解決方案是異步/等待功能。但是我在回調中使用它們,這是我需要初始化的。

// 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,等待不關心或回調返回或try/catch語句的方法...

+1

另一個選項是async.js,它爲您提供了許多用於異步工作的流控制選項。 – Paul

+0

@Paul謝謝,我已經看過async.js和bluebird.js,我更喜歡東西更原生的方式(不要求雖然) – F1ks3r

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(); 


隨着承諾(需要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()); 
0

你甚至不需要承諾/異步等待或其他庫:

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將是一個很好的解決方案

相關問題