3个请求函数的数组 – 如何仅当第一个函数的响应包含string时调用第二个函数? – 节点JS

我有一个3个函数的数组,使用节点提取从3个不同的API获取数据。 如果第一个函数的response.body包含“rejected”,我只想调用第二个和第三个函数。

我遇到的问题是所有的方法在从第一个接收到响应之前被调用。

const buyersList = [ { buyerName: 'ACME', buyerPrice: '100', buyerMethod: sellACME, }, { buyerName: 'ACME', buyerPrice: '60', buyerMethod: sellACME, }, { buyerName: 'ACME', buyerPrice: '20', buyerMethod: sellACME, }, { buyerName: 'ACME', buyerPrice: '2', buyerMethod: sellACME, }, ]; //fetch the data and parse function sellACME(url) { return fetch(url, { method: 'POST' }) .then(obj => parseResponse(obj)) .catch(err => console.log(' error', err)); } //shift the first item in array and execute the method for first item. const methods = {}; methods.exBuyerSell = (url) => { const currBuyer = buyersList.shift(); return currBuyer.buyerMethod(url); }; //loop through array. module.exports = (url, res) => { while (buyersList.length > 0) { methods.exBuyerSell(url) .then((buyerRes) => { //if response.result is accepted, empty array, send response to client. if (buyerRes.result === 'accepted') { buyersList.length = 0; res.json(buyerRes); } //if response.result is rejected, execute the next item in array. if (buyerRes.result === 'rejected') { methods.exBuyerSell(url); } return buyerRes; }); } }; 

这里的业务逻辑是,如果数据被传送给第一个买家,则数据被该买家接受并且不能被呈现给第二个买家。

setTimeout()不是一个选项,因为数组可以增长到20,每个请求最多可能需要180秒。

我试图使用async / await和async.waterfall,但似乎仍然有相同的问题。

这个概念可以应用于你自己的用例。 它将迭代收集,直到承诺解决:

 pipePromises([2,4,6,1], calculateOddity).then(res => console.log(res)) function pipePromises(ary, promiser) { return ary.slice(1, ary.size).reduce( (promise, n) => promise.catch(_ => promiser(n)), promiser(ary[0]) ); } function calculateOddity(n) { return new Promise((resolve, reject) => { n % 2 === 0 ? reject(n) : resolve(n); }) } 

问题是fetch()返回一个承诺,这些承诺将在未来的未知时间被解决或拒绝。

“我遇到的问题是所有的方法在从第一个接收到响应之前被调用。

那是因为while是一个同步函数。 它将执行并不会等待promise fetch()的响应;

当条件满足时,下面的代码不会停止所有的方法被调用,但是它可以防止对客户机提前发送响应:

 // modify this function and just return the promise from fetch() function sellACME(url) { return fetch(url, { method: 'POST' }); } // on your loop, collect all the promises in // the done variable // then use Promise.all to traverse thru all // the promises returned by fetch once all of // promises are done executing module.exports = (url, res) => { let done = []; let result; while (buyersList.length > 0) { done.push(methods.exBuyerSell(url)); } Promise.all(done).then(values => { values.forEach(function (value) { if (value.result === "accepted") { result = value; } }); res.json(result); }); }; 

检查MDN JavaScript Promise.all()参考