在javascript中的一系列函数之后返回

在javascript中的一系列函数之后返回,javascript,node.js,promise,q,Javascript,Node.js,Promise,Q,我也尝试过这样做,但似乎都没能成功。在尝试了这些之后,我尝试了我自己的方式。我不认为这会奏效,但我想我会尝试一下。我感到困惑,因为在某种意义上,回调中存在回调。以下是我想做的功能: var getPrice = function(theData) { var wep = theData.weapon; var completed = 0; for (i = 0; i < theData.skins.length; i++) { var currSkin = theData.skin

我也尝试过这样做,但似乎都没能成功。在尝试了这些之后,我尝试了我自己的方式。我不认为这会奏效,但我想我会尝试一下。我感到困惑,因为在某种意义上,回调中存在回调。以下是我想做的功能:

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

由于对
getSinglePrice()
的每次调用都会发送一个GET请求,因此需要一些时间才能返回响应。如有任何建议或帮助,将不胜感激

你的方法很复杂

我认为最好的方法是做一个所有价格的要求。现在,对于每一个价格,你都要做一个请求。 如果您有一个包含请求所需数据的列表(数组),那么返回值应该是一个包含价格的列表


如果上述方法不可行,您可以阅读有关批处理http请求的更多信息:

需要一些说明-您是否尝试在客户端运行此操作?看起来这是在服务器端的nodejs程序中运行的。如果是这样,您是否愿意将此逻辑推送到客户端并使用Ajax处理。我相信浏览器能够更好地处理多个http请求响应。

因为您没有发布关于csgoMarket.getSinglePrice函数的太多信息,所以我编写了一个使用返回承诺的函数。这将允许您使用Q.all,您应该仔细阅读,因为它在您的情况下确实有帮助

我已经创建了一个内部和外部循环数组来实现我们的承诺。这段代码完全没有经过测试,因为您没有做任何修改

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)
        }
    })
}
var getPrice=函数(数据){
var wep=数据武器;
var完成=0;
var promissions\u outer=[]//用于保存承诺数组的数组
对于(var i=0;i
首先
csgomarket.getSinglePrice()
需要得到批准。这里有一个适配器函数,它调用
csgomarket.getSinglePrice()
并返回
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()
在所有单个
getSinglePriceAsync()
promissions结算时返回一个结算的承诺,这很简单:

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;
    });
}
但是,
data.skinData[data.skin][data.wear]
将略微简化为
data.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);
});

如果答案使用Q可以吗?@thefourtheye是的,很好。我只是不能让它与q一起工作,但如果它使用它就好了!你也可以发布你的csgomarket.getSinglePrice函数吗?这必须在服务器端。浏览器阻止了我对Steam的请求,因为它不支持JSONP,正如我在这里的问题中所看到的:。我今天会尝试一下,然后再给你回复。很抱歉没有包括这个。这里是函数,谢谢你的帮助!为了让它工作,我不得不做一些改变。我是否应该编辑您的答案以反映我所做的更改?是的,请尝试。我很想看看你有什么需要改变的。尼克,好的,我在整理了一下后批准了你的编辑。
getPrice(myData).then(function(data) {
    // use `data` here.
}).catch(function(e) {
    //something went wrong!
    console.log(e);
});