return经过javascript中的一系列函数
return after a series of functions in javascript
我已经尝试用 q as well as async 来做到这一点,但似乎没能成功。在尝试了这些之后,我尝试了自己的方式。我认为这行不通,但我想我会试一试。我很困惑,因为从某种意义上说,回调中有一个回调。这是我想要执行的功能:
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;
}
})
}
}
}
我知道这类问题在 javascript 中很常见,因为我以前 运行 遇到过这些问题,但不确定如何解决这个问题。我想用方法返回的所有数据填充我的对象:
csgomarket.getSinglePrice(wep, currSkin, wears[k], false,
function(err, data) { });
由于每次调用 getSinglePrice()
都会发出 GET 请求,因此需要一些时间才能返回响应。任何建议或帮助将不胜感激!
你的做法很复杂
我认为最好的方法是对所有价格进行 1 次请求。现在,对于每个价格,您都提出一个请求。
如果您有一个包含请求所需数据的列表(数组),则 return 值应该是包含价格的列表。
如果上述方法不可行,您可以阅读有关批处理 http 请求的更多信息:http://jonsamwell.com/batching-http-requests-in-angular/
需要一些说明 - 您是否尝试 运行 在客户端进行此操作?看起来这是 运行ning 在服务器端的 nodejs 程序中。如果是这样,您是否愿意将此逻辑推送到客户端并使用 Ajax 进行处理。我相信浏览器能够更好地处理多个 http 请求-响应。
由于您没有 post 关于您的 csgoMarket.getSinglePrice 函数的太多信息,我写了一个使用 returns 承诺的函数。这将允许您使用 Q.all,您应该仔细阅读它,因为它对您的情况确实有帮助。
我已经创建了一个内部和外部循环数组来实现我们的承诺。此代码完全未经测试,因为您没有提供 fiddle.
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)
}
})
}
首先csgomarket.getSinglePrice()
需要承诺。这是调用 csgomarket.getSinglePrice()
和 return 一个 Q
承诺的适配器函数。
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()
到 return 一个在所有个人 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()
现在 return 是一个承诺,它必须按如下方式使用:
getPrice(myData).then(function(data) {
// use `data` here.
}).catch(function(e) {
//something went wrong!
console.log(e);
});
我已经尝试用 q as well as async 来做到这一点,但似乎没能成功。在尝试了这些之后,我尝试了自己的方式。我认为这行不通,但我想我会试一试。我很困惑,因为从某种意义上说,回调中有一个回调。这是我想要执行的功能:
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;
}
})
}
}
}
我知道这类问题在 javascript 中很常见,因为我以前 运行 遇到过这些问题,但不确定如何解决这个问题。我想用方法返回的所有数据填充我的对象:
csgomarket.getSinglePrice(wep, currSkin, wears[k], false,
function(err, data) { });
由于每次调用 getSinglePrice()
都会发出 GET 请求,因此需要一些时间才能返回响应。任何建议或帮助将不胜感激!
你的做法很复杂
我认为最好的方法是对所有价格进行 1 次请求。现在,对于每个价格,您都提出一个请求。 如果您有一个包含请求所需数据的列表(数组),则 return 值应该是包含价格的列表。
如果上述方法不可行,您可以阅读有关批处理 http 请求的更多信息:http://jonsamwell.com/batching-http-requests-in-angular/
需要一些说明 - 您是否尝试 运行 在客户端进行此操作?看起来这是 运行ning 在服务器端的 nodejs 程序中。如果是这样,您是否愿意将此逻辑推送到客户端并使用 Ajax 进行处理。我相信浏览器能够更好地处理多个 http 请求-响应。
由于您没有 post 关于您的 csgoMarket.getSinglePrice 函数的太多信息,我写了一个使用 returns 承诺的函数。这将允许您使用 Q.all,您应该仔细阅读它,因为它对您的情况确实有帮助。
我已经创建了一个内部和外部循环数组来实现我们的承诺。此代码完全未经测试,因为您没有提供 fiddle.
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)
}
})
}
首先csgomarket.getSinglePrice()
需要承诺。这是调用 csgomarket.getSinglePrice()
和 return 一个 Q
承诺的适配器函数。
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()
到 return 一个在所有个人 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()
现在 return 是一个承诺,它必须按如下方式使用:
getPrice(myData).then(function(data) {
// use `data` here.
}).catch(function(e) {
//something went wrong!
console.log(e);
});