在循环

时间:2017-07-27 12:44:18

标签: node.js object request

我无法在API请求返回的对象之间正确浏览。

基本上,我有一个数组(tickerArr有25个元素,我从另一个请求获得),我用它来代替另一个请求的forEach循环。

这是代码的样子:

var request = require('request');
var async = require('async');
var fs = require('fs')

var getTickerList = require('./getTickerList').getTickerList;
var unixTimeStamp = new Date().toISOString();

async function getTickerInfo() {

  var tickerArr = await getTickerList;
  var arrLength = tickerArr.length;
  var init = 0;

  console.log(`${arrLength} to process to the batchfile...`);
  var getTickerInfo = new Promise((resolve, reject) => {
    async.forEach(tickerArr, (item, callback) => {
      request({
        url:`https://api.kraken.com/0/public/Ticker?pair=${item}`,
        json: true
      }, (error, response, body) => {
        var tickerInfo = JSON.stringify(body.result)
        fs.appendFile(`./modules/batches/${unixTimeStamp}batch.json`, tickerInfo, (err) => {
          if (err) throw err;
          init ++;
          var progress = Math.round(init / arrLength * 100);
          console.log(`[${progress}%] - ${item} successfully added!`);
        });
         resolve();
      })
    });
  });
}

getTickerInfo()

不幸的是,即使请求正常工作,返回的对象也有一个特定的路径:

  
      
  • 错误:[]
  •   
  • 结果:      
        
    • 对(x):      
          
      • a:[1,2,3]
      •   
      • b:[1,2,3]等......
      •   
    •   
  •   

您可以找到从请求here返回的信息的确切示例:

{
    "error": [],
    "result": {
        "XXBTZEUR": {
            "a": ["2212.31000", "3", "3.000"],
            "b": ["2212.21100", "1", "1.000"],
            "c": ["2212.31000", "0.15800000"],
            "v": ["4999.06419498", "9993.55448658"],
            "p": ["2206.04624", "2181.36028"],
            "t": [15065, 29524],
            "l": ["2167.00000", "2122.92000"],
            "h": ["2239.00000", "2239.00000"],
            "o": "2184.99000"
        }
    }
}

唯一的问题是:我想转型'我从请求获得的对象,到另一个对象(只是安排周围的东西,最重要的是:将' Pair(x)'属性作为名称键的值)但是因为我没有&#39 ; t事先知道对(我tickerArray中的值足以发出请求但显然不对应引用对象),我无法访问结果中包含的信息来操纵它。

有人有任何想法吗?

提前致谢!

1 个答案:

答案 0 :(得分:3)

您的问题有多个级别,也许最好先将任务分解为其组成部分。

  1. 调用Kraken REST API并解包响应
  2. 创建小型,可组合的功能
  3. 将对象转换为新布局
  4. 将结果写入文件
  5. 0。前言

    由于您希望使用await,首先要知道的是,这是#34的语法糖;等待承诺解决"。 async是在函数内启用await语义的关键字。

    所以给出了这个承诺返回功能:

    function foo() {
        return Promise.resolve('some value');
    }
    

    这样:

    async function worker() {
        var fooResult = await foo();
        console.log(fooResult);
    }
    worker();
    

    和此:

    foo().then(function worker(fooResult) {
        console.log(fooResult);
    });
    

    实际上是一回事。 (一如既往,它比这复杂一点,但这是它的要点。)

    由于我们在这里使用promises,最明智的做法是使用也使用promises的库。 requestrequest-promise反对,所以让我们使用它。

    var request = require('request-promise');
    

    1。调用Kraken REST API并解包响应

    发出HTTP请求并分解响应(errresult部分)对所有API端点的工作方式相同,因此我们可以编写一个处理此任务的函数。

    function getFromApi(endpoint, params) {
        return request({
            url: "https://api.kraken.com/0/public/" + endpoint,
            qs: params,
            json: true
        }).then(function (data) {
            if (data.error && data.error.length) {
                throw new Error(`API error xyz for ${endpoint} with params ...`);
            }
            return data.result;
        });
    }
    

    此功能的用户根本不必处理err并且可以直接访问result

    2。创建小型可组合函数

    我们的getFromApi()函数返回一个promise,因此我们可以在各种API端点的包装器中重用它:

    function getTickerList() {
        return getFromApi("TickerList"); // ...or something like that
    }
    
    function getSingleTicker(pair) {
        return getFromApi("Ticker", {pair: pair}).then(transformTicker);
    }
    
    function getTickerInfo(tickerList) {
        return Promise.all(tickerList.map(getSingleTicker));
    }
    

    请注意,与getFromApi()一样,我们可以使用Promise#then来修改操作的整体输出。

    getTickerInfo()接受一系列代码名称。它使用Array#map并行运行所有API请求,Promise#all允许等待整体结果。获取和转换多个并行的相当复杂的操作组成了一个非常直接的单行。

    3。将对象转换为新布局

    transformTicker()用于接受{"XXBTZEUR": {"a": [...], ... }}形式的对象,并返回其变换后的变体。

    function transformTicker(ticker) {
      var result = {};
    
      // ...massage ticker into desired form
      Object.keys(ticker).forEach( pair => {
          Object.keys(ticker[pair]).forEach( k => {
              result[k] = { /* ... */ };
          });
      });
    
      return result;
    }
    

    4。将结果写入文件

    附加到JSON文件不起作用。 JSON只能作为一个整体进行读写。让我们获取一个自动收录器名称列表,相关的代码并将结果写入文件。

    async function worker() {
        var tickerList = await getTickerList();
        var tickerInfo = await getTickerInfo(tickerList);
        var filename = `./modules/batches/${new Date().toISOString()}batch.json`;
    
        fs.writeFile(filename, JSON.stringify(tickerInfo), (err) => {
            if (err) throw err;
            console.log("Done");
        });
    }
    
    worker();
    

    您可以切换使用fs模块的promisified版本(see Bluebird#promisifyAll),因为普通版本通过要求延续回调再次打破了漂亮的async / await语义。

    使用已宣传的fs模块,工作人员可能如下所示:

    async function worker() {
        var tickerList = await getTickerList();
        var tickerInfo = await getTickerInfo(tickerList);
        var filename = `./modules/batches/${new Date().toISOString()}batch.json`;
    
        await fs.writeFileAsync(filename, JSON.stringify(tickerInfo));
        console.log("Done");
    }