在javascript中返回一系列函数之后
我曾试图用q和async来做到这一点,但似乎无法使其工作。 试过后,我尝试了我自己的方式。 我不认为这会起作用,但我想我会试一试。 我感到困惑,因为在某种意义上,callback中存在callback。 这是我想要做的function:
var getPrice = function(theData) { var wep = theData.weapon; var completed = 0; for (i = 0; i < theData.skins.length; i++) { var currSkin = theData.skins[i]; theData.skinData[currSkin] = {}; for (k = 0; k < wears.length; k++) { csgomarket.getSinglePrice(wep, currSkin, wears[k], false, function(err, data) { completed++; if (!err) { theData.skinData[data.skin][data.wear] = data; } if (completed === theData.skins.length*wears.length) { return theData; } }) } } }
我知道这些types的问题在JavaScript中很常见,因为我之前遇到过这些问题,但不知道如何解决这个问题。 我想要用方法返回的所有数据填充我的对象:
csgomarket.getSinglePrice(wep, currSkin, wears[k], false, function(err, data) { });
由于每次调用getSinglePrice()
都会发送一个GET请求,因此响应需要一段时间才能返回。 任何build议或帮助将不胜感激!
首先csgomarket.getSinglePrice()
需要promisified。 这里有一个调用函数csgomarket.getSinglePrice()
并返回一个Q
promise。
function getSinglePriceAsync(wep, skin, wear, stattrak) { return Q.Promise(function(resolve, reject) { // may be `Q.promise(...)` (lower case P) depending on Q version. csgomarket.getSinglePrice(wep, skin, wear, stattrak, function(err, result) { if(err) { reject(err); } else { resolve(result); } }); }); }
现在,你想要getPrice()
返回一个承诺,当所有的个人getSinglePriceAsync()
承诺解决,这是微不足道的:
var getPrice = function(theData) { var promises = [];//array in which to accumulate promises theData.skins.forEach(function(s) { theData.skinData[s] = {}; wears.forEach(function(w) { promises.push(getSinglePriceAsync(theData.weapon, s, w, false).then(function(data) { theData.skinData[data.skin][data.wear] = data; })); }); }); //return a single promise that will settle when all the individual promises settle. return Q.allSettled(promises).then(function() { return theData; }); }
但是, theData.skinData[data.skin][data.wear]
会稍微简化为theData.skinData[s][w]
:
var getPrice = function(theData) { var promises = [];//array in which to accumulate promises theData.skins.forEach(function(s) { theData.skinData[s] = {}; // wears.forEach(function(w) { promises.push(getSinglePriceAsync(theData.weapon, s, w, false).then(function(data) { theData.skinData[s][w] = data; })); }); }); //return a single promise that will settle when all the individual `promises` settle. return Q.allSettled(promises).then(function() { return theData; }); }
这种简化将会起作用,因为forEach(function() {...})
会导致s
被困在闭包中。
由于getPrice()
现在返回一个承诺,它必须如下使用:
getPrice(myData).then(function(data) { // use `data` here. }).catch(function(e) { //something went wrong! console.log(e); });
你的方法非常复杂。
我认为最好的办法是做所有的价格1请求。 现在,对于每一个价格你做一个请求。 如果你有一个需要请求的数据的列表(数组),返回值应该是一个包含价格的列表。
如果上面的方法是不可能的,你可以阅读更多关于批量http请求:http: //jonsamwell.com/batching-http-requests-in-angular/
需要一些澄清 – 你是否试图在客户端运行这个? 看起来这是在服务器端的nodejs程序中运行。 如果是这样,你是不是把这个逻辑推到客户端,并用Ajax处理。 我相信浏览器能够更好地处理多个http请求响应。
既然你没有发布关于你的csgoMarket.getSinglePrice函数的很多信息,我写了一个使用返回一个承诺。 这将允许你使用你应该阅读的Q.all,因为它会真正帮助你的情况。
我创build了一个内部和外部循环数组来保存我们的承诺。 这个代码是完全没有经过testing,因为你没有提起小提琴。
var getPrice = function(theData) { var wep = theData.weapon; var completed = 0; var promises_outer = [] //array to hold the arrays of our promises for (var i = 0; i < theData.skins.length; i++) { var currSkin = theData.skins[i]; theData.skinData[currSkin] = {}; var promises_inner = [] // an array to hold our promises for (var k = 0; k < wears.length; k++) { //wears.length is referenced to below but not decalared anywhere in the function. It's either global or this function sits somewhere where it has access to it promises_inner.push(csgomarket.getSinglePrice(wep, currSkin, wears[k], false)) } promises_outer.push(promises_inner) } promises_outer.forEach(function(el, index){ var currSkin = theData.skins[index] theData.skinData[currSkin] = {} Q.all(el).then(function(data){ //data is an array of results in the order you made the calls if(data){ theData.skinData[data.skin][data.wear] = data } }) }) } var csgomarket = {} csgomarket.getSinglePrice = function(wep, currSkin, wears, someBoolean){ return Q.promise(function (resolve, reject){ //do your request or whatever you do var result = true var data = { skin : "cool one", wear : "obviously" } var error = new Error('some error that would be generated') if(result){ resolve(data) } else { reject(error) } }) }
- 开始使用节点,等待本地主机
- Gulp运行在windows |上运行失败 错误消息:Microsoft JScript编译错误,无效的字符
- Socket.io发射两次
- Node.JS + mongo:.find()。each()在第一批后停止
- 如何使用`Meteor.bindEnvironment`绑定?
- 使用节点服务器与NowJS发送JavaScript文件
- 用Javascript / Node.js在代码里执行mongoimport
- socket.io(nodejs)发出的callback是否通过在callback完成期间阻塞服务器来影响服务器的性能?
- 数据从一个函数的asynchronous执行与另一个函数的执行混合在一起