进行多次Http调用并使用Promises巩固结果

时间:2016-03-18 02:02:47

标签: javascript node.js asynchronous

好的,我发现类似的问题已经解决了我的问题但不完全正确。

示例:

Nodejs making parallel http calls and consolidate the result

Node.js - wait for multiple async calls

我有8个函数做同样的事情接受命中一个不同的api端点。在这些函数中,我查看响应并选择我想要的并返回。然后我有一个函数使用bluebird立即进行所有调用并等待他们的响应。

这是8个函数中的一个看起来像(几乎只是换掉它正在击中的api)。

function getMorphite(){
request.get(crestMarketHistoryMorphite , function (error, response, body) {
    if (!error && response.statusCode === 200) {
        var content = JSON.parse(body);
        var topMorphiteBuy;
        var maxBuy = 0;
        for(var i = 0; i < content.items.length; i++){
            var item = content.items[i];
            if(item.location.id == 60003760){
                var buyPrice = item.price;
                if(buyPrice > maxBuy){
                    maxBuy = buyPrice;
                    topMorphiteBuy = item;
                }
            }
        }
        console.log(topMorphiteBuy);
        return topMorphiteBuy
    } else {
        console.error(error);
        return error;
    }
});
}

这是我的功能抓住我的所有功能,运行它们,并抓住他们的回答。

exports.getSearchResults = function (req, res) {
var allItems = [];
Promise.all([getTritanium(), getPyrite(), getMexallon(), getIsogen(), getNocxium(), getZydrine(), getMegactye(), getMorphite()]).then(function (response) {
    console.log("Response", response);
    allItems.push(response[0]);
    allItems.push(response[1]);
    allItems.push(response[2]);
    allItems.push(response[3]);
    allItems.push(response[4]);
    allItems.push(response[5]);
    allItems.push(response[6]);
    allItems.push(response[7]);
    res.type('application/json');
    res.json(allItems);
});
};

所以这个&#39;工作&#39;但我有一些回归问题。现在,响应是一个由8个未定义项组成的数组。我到底错过了什么。它必须是一个回归问题,但我觉得我已经恐慌地转换所有返回语句而没有运气。

1 个答案:

答案 0 :(得分:2)

Promise.all()只有等待异步操作才能传递一个promises数组,其中每个promise都链接到相应的操作。现在,您正在传递一个undefined值数组,因为您的getMorphite()函数和其他类似函数实际上并没有返回任何内容。来自``request.get()return getMorphite()callback happen after request()`实现内部的has already long since returned and those return values just go back into the bowels of the语句被忽略。

因为您传递了Promise.all()一系列未定义的值,所以它不会等待任何事情并且它不会得到任何结果。因此,它会立即调用其.then()处理程序,并且除了结果的undefined数组之外什么也没有。

如果你想使用Promise.all()(这是工作的正确工具),那么你需要&#34; promisify&#34;您的request()操作,以便它们返回在异步操作完成时使用最终结果解析的promise。然后,Promise.all()将获得一系列承诺,Promise.all().then()将等待所有承诺完成,并将从这些承诺中获得一系列结果。

如果你正在使用Bluebird,你可以使用它来宣传request.get()这样的操作:

 var request = Promise.promisifyAll(request, {multiArgs: true});

这&#34; promisifyAll&#34; step使用&#34; Async&#34;向request对象添加新方法后缀因此request.get()获取名为request.getAsync()的伴随方法。新的&#34; Async&#34;版本返回一个承诺。通常不需要multiArgs选项,但在这种情况下,因为request.get()返回多个数据参数(这不是通常的节点异步调用约定),所以这里需要它。

而且,这里是getMorphite()的一个实现,它返回一个promise并将最终值作为promise的履行值返回。

function getMorphite() {
    return request.getAsync(crestMarketHistoryMorphite).spread(response, body) {
        if (response.statusCode === 200) {
            var content = JSON.parse(body);
            var topMorphiteBuy;
            var maxBuy = 0;
            for (var i = 0; i < content.items.length; i++) {
                var item = content.items[i];
                if (item.location.id == 60003760) {
                    var buyPrice = item.price;
                    if (buyPrice > maxBuy) {
                        maxBuy = buyPrice;
                        topMorphiteBuy = item;
                    }
                }
            }
            console.log(topMorphiteBuy);
            // return this to make it the fulfilled value of the promise
            return topMorphiteBuy;    
        } else {
            // reject the promise with bad status code
            throw new Error("response.statusCode was: " + response.statusCode)
        }
    });
}

如果您将其他功能更改为也可以这样工作,则可以使用原始代码:

Promise.all([getTritanium(), getPyrite(), getMexallon(), getIsogen(), 
             getNocxium(), getZydrine(), getMegactye(), getMorphite()])
  .then(function (response) {
    console.log("Response", response);
    allItems.push(response[0]);
    allItems.push(response[1]);
    allItems.push(response[2]);
    allItems.push(response[3]);
    allItems.push(response[4]);
    allItems.push(response[5]);
    allItems.push(response[6]);
    allItems.push(response[7]);
    res.type('application/json');
    res.json(response);
});
相关问题