我怎样才能与蓝鸟承诺分页?

我有类似的东西

new Promise (resolve, reject) -> trader.getTrades limit, skip, (err, trades) -> return reject err if err resolve trades .each (trade) -> doStuff trade 

limit设置为某个任意数字,例如10skip0开始。 我想继续增加skip直到没有更多的trades

doStuff是我用来处理每笔交易的函数。

这是第一次,但我想以分页的方式获得更多的交易。 具体来说,我想运行trader.getTrades更高的skip直到trades.length为0

您应该能够使用promisify() / promisifyAll()trader.getTrades()转换为返回承诺的asynchronous版本。 那么,这样的事情应该很好:

 function getAllTrades(limit, offset, query) { var allTrades = []; function getTrades(limit, offset, query){ return trader.getTradesAsync(limit, offset, query) .each(function(trade) { allTrades.push(trade) // or, doStuff(trade), etc. }) .then(function(trades) { if (trades.length === limit) { offset += limit; return getTrades(limit, offset, query); } else { return allTrades; } }) .catch(function(e) { console.log(e.stack); }) } return getTrades(limit, offset, query) } 

如果您事先知道交易总数,则可以使用与.map{concurrency: N}不同的策略来一次获得N页的交易。

首先,让我们来隐藏一下丑陋的callbackAPI:

 var getTrades = Promise.promisify(trader.getTrades, trader); 

现在,要遍历分页API,我们将使用一个简单的recursion下降:

 function getAllTrades(limit, arr) { if (!arr) arr=[]; return getTrades(limit, arr.length).then(function(results) { if (!results.length) return arr; else return getAllTrades(limit, arr.concat(results)); }); } 

不可否认, concat不是超快的,因为它在每次请求之后创build一个新的数组,但这是最优雅的。

这个函数将返回一个承诺,当所有的请求被做出时,这个承诺将会被大量的所有结果解决。 这当然可能不是你想要的 – 也许你想立即显示第一个结果,并只加载更多只懒惰? 那么单一的承诺不是你想要的工具,因为这种行为更像stream。 然而,它可以用承诺书写:

 getTradeChunks = (limit, start = 0) -> getTrades limit, start .then (chunk) -> throw new Error("end of stream") if not chunk.length s = start+chunk.length [chunk, -> getTradeChunks limit, s] rec = ([chunk, cont]) -> Promise.each chunk, doStuff .then -> waitForClick $ "#more" .then cont .then rec, err end = (err) -> $ "#more" .text "no more trades" getTradeChunks 15 .then rec, err 

这是我自己的解决scheme,通过承诺:方法页面 ,作为spex库的一部分。

它还可以让您节制处理,并根据需要提供负载平衡。

 var promise = require('bluebird'); var spex = require('spex')(promise); function source(index, data, delay) { // create and return an array/page of mixed values // dynamically, based on the index of the sequence; switch (index) { case 0: return [0, 1, promise.resolve(2)]; case 1: return [3, 4, promise.resolve(5)]; case 2: return [6, 7, promise.resolve(8)]; } // returning nothing/undefined indicates the end of the sequence; // throwing an error will result in a reject; } function dest(idx, data, delay) { // data - resolved array data; console.log("LOG:", idx, data, delay); } spex.page(source, dest) .then(function (data) { console.log("DATA:", data); // print result; }); 

产量

 LOG: 0 [ 0, 1, 2 ] undefined LOG: 1 [ 3, 4, 5 ] 3 LOG: 2 [ 6, 7, 8 ] 0 DATA: { pages: 3, total: 9, duration: 7 }