最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - NodeJS: TypeError: undefined is not a function - Promise.all - Object.keys - Stack Overflow

programmeradmin4浏览0评论

I'd need your help because I get the typeError mentionned in the question and I'm not sure to understand why. I've got an object (that es back from a request-promise) that looks like this:

{
                   "statusCode": 200,
                   "body": {
                      "BTC_USD": {
                         "buy_price": "4258",
                         "sell_price": "4265",
                         "last_trade": "4265",
                         "high": "4360",
                         "low": "4200",
                         "avg": "4260.2077946",
                         "vol": "219.32404491",
                         "vol_curr": "933982.49730504",
                         "updated": 1503767188
                      },
                      "BTC_EUR": {
                         "buy_price": "3640.1001",
                         "sell_price": "3650",
                         "last_trade": "3644.8",
                         "high": "3801.999999",
                         "low": "3622.000006",
                         "avg": "3685.0414084",
                         "vol": "94.48595035",
                         "vol_curr": "347993.56447153",
                         "updated": 1503767128
                      },
                      "BTC_RUB": {
                         "buy_price": "243511",
                         "sell_price": "244340",
                         "last_trade": "243511.49870226",
                         "high": "248786.99",
                         "low": "239630",
                         "avg": "243430.47675799",
                         "vol": "140.12303781",
                         "vol_curr": "34185015.26771479",
                         "updated": 1503767190
                      },
                      "BTC_UAH": {
                         "buy_price": "107000",
                         "sell_price": "107790",
                         "last_trade": "107790",
                         "high": "109900",
                         "low": "105354",
                         "avg": "108167.30195869",
                         "vol": "34.94251977",
                         "vol_curr": "3770330.73968614",
                         "updated": 1503767167
                      },
                      "DASH_BTC": {
                         "buy_price": "0.08528559",
                         "sell_price": "0.08644069",
                         "last_trade": "0.086196",
                         "high": "0.093364",
                         "low": "0.07043",
                         "avg": "0.0803689",
                         "vol": "1595.2753788",
                         "vol_curr": "123.76291968",
                         "updated": 1503767189
                      },
                   },
                   "request": {
                      "uri": {
                         "protocol": "https:",
                         "slashes": true,
                         "auth": null,
                         "host": "api.exmo",
                         "port": 443,
                         "hostname": "api.exmo",
                         "hash": null,
                         "search": null,
                         "query": null,
                         "pathname": "/v1/ticker/",
                         "path": "/v1/ticker/",
                         "href": "/"
                      },
                      "method": "GET",
                      "headers": {
                         "accept": "application/json"
                      }
                  }
                }

as you can see, the body has multiple objects and my goal is to rearrange the info in a new layout for each body.keys:

Object.keys(res.body).forEach((k) => {
          result= {
            mk: 'exmo',
            name: k,
            a: res.body[k].sell_price,
            b: res.body[k].buy_price,
            c: res.body[k].last_trade,
            v: res.body[k].vol,
            t: res.body[k].vol_curr,
            l: res.body[k].low,
            h: res.body[k].high,
            sn: res.body[k].updated,
          }
        });
        return result;

But for some reason it's not working... I feel like I'm not using the Promise.all properly?

Here's my full code for testing (it reproduces the error):

function exmo() {
  Promise.all(
    function () {
        var result = {};
        var res = {
                   "statusCode": 200,
                   "body": {
                      "BTC_USD": {
                         "buy_price": "4258",
                         "sell_price": "4265",
                         "last_trade": "4265",
                         "high": "4360",
                         "low": "4200",
                         "avg": "4260.2077946",
                         "vol": "219.32404491",
                         "vol_curr": "933982.49730504",
                         "updated": 1503767188
                      },
                      "BTC_EUR": {
                         "buy_price": "3640.1001",
                         "sell_price": "3650",
                         "last_trade": "3644.8",
                         "high": "3801.999999",
                         "low": "3622.000006",
                         "avg": "3685.0414084",
                         "vol": "94.48595035",
                         "vol_curr": "347993.56447153",
                         "updated": 1503767128
                      },
                      "BTC_RUB": {
                         "buy_price": "243511",
                         "sell_price": "244340",
                         "last_trade": "243511.49870226",
                         "high": "248786.99",
                         "low": "239630",
                         "avg": "243430.47675799",
                         "vol": "140.12303781",
                         "vol_curr": "34185015.26771479",
                         "updated": 1503767190
                      },
                      "BTC_UAH": {
                         "buy_price": "107000",
                         "sell_price": "107790",
                         "last_trade": "107790",
                         "high": "109900",
                         "low": "105354",
                         "avg": "108167.30195869",
                         "vol": "34.94251977",
                         "vol_curr": "3770330.73968614",
                         "updated": 1503767167
                      },
                      "DASH_BTC": {
                         "buy_price": "0.08528559",
                         "sell_price": "0.08644069",
                         "last_trade": "0.086196",
                         "high": "0.093364",
                         "low": "0.07043",
                         "avg": "0.0803689",
                         "vol": "1595.2753788",
                         "vol_curr": "123.76291968",
                         "updated": 1503767189
                      },
                   },
                   "request": {
                      "uri": {
                         "protocol": "https:",
                         "slashes": true,
                         "auth": null,
                         "host": "api.exmo",
                         "port": 443,
                         "hostname": "api.exmo",
                         "hash": null,
                         "search": null,
                         "query": null,
                         "pathname": "/v1/ticker/",
                         "path": "/v1/ticker/",
                         "href": "/"
                      },
                      "method": "GET",
                      "headers": {
                         "accept": "application/json"
                      }
                  }
                }
        Object.keys(res.body).forEach((k) => {
          result= {
            mk: 'exmo',
            name: k,
            a: res.body[k].sell_price,
            b: res.body[k].buy_price,
            c: res.body[k].last_trade,
            v: res.body[k].vol,
            t: res.body[k].vol_curr,
            l: res.body[k].low,
            h: res.body[k].high,
            sn: res.body[k].updated,
          }
        });
        return result;
    }).then((data) => {
    console.log(JSON.stringify(data, null, 3));
  })
};

exmo();

thanks in advance to you all for your help!

***** EDIT *****: [Trying to clarify] My objective was to get a single object per iteration of forEach. Ultimately each of these object would go into a mongo database. I'm using incorrectly Promise.all (because it needs an array of promises) but was looking for a similar solution.

I'd need your help because I get the typeError mentionned in the question and I'm not sure to understand why. I've got an object (that es back from a request-promise) that looks like this:

{
                   "statusCode": 200,
                   "body": {
                      "BTC_USD": {
                         "buy_price": "4258",
                         "sell_price": "4265",
                         "last_trade": "4265",
                         "high": "4360",
                         "low": "4200",
                         "avg": "4260.2077946",
                         "vol": "219.32404491",
                         "vol_curr": "933982.49730504",
                         "updated": 1503767188
                      },
                      "BTC_EUR": {
                         "buy_price": "3640.1001",
                         "sell_price": "3650",
                         "last_trade": "3644.8",
                         "high": "3801.999999",
                         "low": "3622.000006",
                         "avg": "3685.0414084",
                         "vol": "94.48595035",
                         "vol_curr": "347993.56447153",
                         "updated": 1503767128
                      },
                      "BTC_RUB": {
                         "buy_price": "243511",
                         "sell_price": "244340",
                         "last_trade": "243511.49870226",
                         "high": "248786.99",
                         "low": "239630",
                         "avg": "243430.47675799",
                         "vol": "140.12303781",
                         "vol_curr": "34185015.26771479",
                         "updated": 1503767190
                      },
                      "BTC_UAH": {
                         "buy_price": "107000",
                         "sell_price": "107790",
                         "last_trade": "107790",
                         "high": "109900",
                         "low": "105354",
                         "avg": "108167.30195869",
                         "vol": "34.94251977",
                         "vol_curr": "3770330.73968614",
                         "updated": 1503767167
                      },
                      "DASH_BTC": {
                         "buy_price": "0.08528559",
                         "sell_price": "0.08644069",
                         "last_trade": "0.086196",
                         "high": "0.093364",
                         "low": "0.07043",
                         "avg": "0.0803689",
                         "vol": "1595.2753788",
                         "vol_curr": "123.76291968",
                         "updated": 1503767189
                      },
                   },
                   "request": {
                      "uri": {
                         "protocol": "https:",
                         "slashes": true,
                         "auth": null,
                         "host": "api.exmo.",
                         "port": 443,
                         "hostname": "api.exmo.",
                         "hash": null,
                         "search": null,
                         "query": null,
                         "pathname": "/v1/ticker/",
                         "path": "/v1/ticker/",
                         "href": "https://api.exmo./v1/ticker/"
                      },
                      "method": "GET",
                      "headers": {
                         "accept": "application/json"
                      }
                  }
                }

as you can see, the body has multiple objects and my goal is to rearrange the info in a new layout for each body.keys:

Object.keys(res.body).forEach((k) => {
          result= {
            mk: 'exmo',
            name: k,
            a: res.body[k].sell_price,
            b: res.body[k].buy_price,
            c: res.body[k].last_trade,
            v: res.body[k].vol,
            t: res.body[k].vol_curr,
            l: res.body[k].low,
            h: res.body[k].high,
            sn: res.body[k].updated,
          }
        });
        return result;

But for some reason it's not working... I feel like I'm not using the Promise.all properly?

Here's my full code for testing (it reproduces the error):

function exmo() {
  Promise.all(
    function () {
        var result = {};
        var res = {
                   "statusCode": 200,
                   "body": {
                      "BTC_USD": {
                         "buy_price": "4258",
                         "sell_price": "4265",
                         "last_trade": "4265",
                         "high": "4360",
                         "low": "4200",
                         "avg": "4260.2077946",
                         "vol": "219.32404491",
                         "vol_curr": "933982.49730504",
                         "updated": 1503767188
                      },
                      "BTC_EUR": {
                         "buy_price": "3640.1001",
                         "sell_price": "3650",
                         "last_trade": "3644.8",
                         "high": "3801.999999",
                         "low": "3622.000006",
                         "avg": "3685.0414084",
                         "vol": "94.48595035",
                         "vol_curr": "347993.56447153",
                         "updated": 1503767128
                      },
                      "BTC_RUB": {
                         "buy_price": "243511",
                         "sell_price": "244340",
                         "last_trade": "243511.49870226",
                         "high": "248786.99",
                         "low": "239630",
                         "avg": "243430.47675799",
                         "vol": "140.12303781",
                         "vol_curr": "34185015.26771479",
                         "updated": 1503767190
                      },
                      "BTC_UAH": {
                         "buy_price": "107000",
                         "sell_price": "107790",
                         "last_trade": "107790",
                         "high": "109900",
                         "low": "105354",
                         "avg": "108167.30195869",
                         "vol": "34.94251977",
                         "vol_curr": "3770330.73968614",
                         "updated": 1503767167
                      },
                      "DASH_BTC": {
                         "buy_price": "0.08528559",
                         "sell_price": "0.08644069",
                         "last_trade": "0.086196",
                         "high": "0.093364",
                         "low": "0.07043",
                         "avg": "0.0803689",
                         "vol": "1595.2753788",
                         "vol_curr": "123.76291968",
                         "updated": 1503767189
                      },
                   },
                   "request": {
                      "uri": {
                         "protocol": "https:",
                         "slashes": true,
                         "auth": null,
                         "host": "api.exmo.",
                         "port": 443,
                         "hostname": "api.exmo.",
                         "hash": null,
                         "search": null,
                         "query": null,
                         "pathname": "/v1/ticker/",
                         "path": "/v1/ticker/",
                         "href": "https://api.exmo./v1/ticker/"
                      },
                      "method": "GET",
                      "headers": {
                         "accept": "application/json"
                      }
                  }
                }
        Object.keys(res.body).forEach((k) => {
          result= {
            mk: 'exmo',
            name: k,
            a: res.body[k].sell_price,
            b: res.body[k].buy_price,
            c: res.body[k].last_trade,
            v: res.body[k].vol,
            t: res.body[k].vol_curr,
            l: res.body[k].low,
            h: res.body[k].high,
            sn: res.body[k].updated,
          }
        });
        return result;
    }).then((data) => {
    console.log(JSON.stringify(data, null, 3));
  })
};

exmo();

thanks in advance to you all for your help!

***** EDIT *****: [Trying to clarify] My objective was to get a single object per iteration of forEach. Ultimately each of these object would go into a mongo database. I'm using incorrectly Promise.all (because it needs an array of promises) but was looking for a similar solution.

Share Improve this question edited Aug 26, 2017 at 19:41 Martin Carre asked Aug 26, 2017 at 17:57 Martin CarreMartin Carre 1,2494 gold badges23 silver badges45 bronze badges 8
  • 1 Please tell us what output you are trying to end up with. – jfriend00 Commented Aug 26, 2017 at 18:06
  • 1 More than "needs to be rewritten" is "just remove some line of code", pastebin./raw/znLHzvz7 Is that what you want? – Federkun Commented Aug 26, 2017 at 18:09
  • 3 Promise.all() should be passed an array of promises. You are passing it a function which will never be called. For starters, remove the Promise.all() entirely. – jfriend00 Commented Aug 26, 2017 at 18:10
  • Don't use forEach. Also what are you trying to do with result? – Bergi Commented Aug 26, 2017 at 18:16
  • 2 Voting to close as this question is simply unclear and the OP is not around to clarify. – jfriend00 Commented Aug 26, 2017 at 18:41
 |  Show 3 more ments

3 Answers 3

Reset to default 3

Your question is plicated a little by your code being all lumped in together, so here I've split it up.

This function mimics your server response as an example to show you how the promise can be managed.

function getData() {
  return new Promise((resolve, reject) => {

    // Parse the returned data
    resolve(JSON.parse(res));
  });
}

Then you need to transform your data. Here you can use map to iterate over the obj instead of forEach:

function mapData(obj) {
  return Object.keys(obj.body).map((k) => {
    return {
      mk: 'exmo',
      name: k,
      a: res.body[k].sell_price,
      b: res.body[k].buy_price,
      c: res.body[k].last_trade,
      v: res.body[k].vol,
      t: res.body[k].vol_curr,
      l: res.body[k].low,
      h: res.body[k].high,
      sn: res.body[k].updated
    }
  });
}

Then you can simply call getData, mapData, and then output the result. You don't want Promise.all here because that method only accepts an array of promises.

getData()
  .then(mapData)
  .then(data => console.log(JSON.stringify(data, null, 3)));

DEMO (n.b. this demo uses your parsed obj so doesn't reparse it again in getData).

As you can see, you're reassigning result over and over in the sane loop forEach(), the return at the end could only return the information of the last key in body.
What you need to do is to put all values with the same key in an array (maybe?). Or in a simpler way: transpose the whole table.
Therefore, you gotta declare bunch of Array's at the first place:

// init
let result = { };
let keys = ['buy_price', 'sell_price', /* etc. */];
keys.forEach(k => result[k] = []);

// gathering informations
Object.keys(res.body).forEach(name =>
    Object.keys(res.body[name]).forEach(k => result[k].push(res.body[name][k]))
);

Now you can easily get your information by the index from result.

If you want to index'em by their original names, you can firstly initialize result as a bunch of Object's, then use the name instead of directly push() in the inner forEach().

Object.keys(res.body[name]).forEach(k => result[k][name] = res.body[name][k])

Which makes more sense on 'transposing' the whole table.

Promise.all(iterable) it take an iterable object such as an Array or String.

I modified your code, it's giving output. Note :- your code logic i did't not change, it give result as your logic.

function exmo() {
  var data = (function () {
        var result = {};
        var res = {
                   "statusCode": 200,
                   "body": {
                      "BTC_USD": {
                         "buy_price": "4258",
                         "sell_price": "4265",
                         "last_trade": "4265",
                         "high": "4360",
                         "low": "4200",
                         "avg": "4260.2077946",
                         "vol": "219.32404491",
                         "vol_curr": "933982.49730504",
                         "updated": 1503767188
                      },
                      "BTC_EUR": {
                         "buy_price": "3640.1001",
                         "sell_price": "3650",
                         "last_trade": "3644.8",
                         "high": "3801.999999",
                         "low": "3622.000006",
                         "avg": "3685.0414084",
                         "vol": "94.48595035",
                         "vol_curr": "347993.56447153",
                         "updated": 1503767128
                      },
                      "BTC_RUB": {
                         "buy_price": "243511",
                         "sell_price": "244340",
                         "last_trade": "243511.49870226",
                         "high": "248786.99",
                         "low": "239630",
                         "avg": "243430.47675799",
                         "vol": "140.12303781",
                         "vol_curr": "34185015.26771479",
                         "updated": 1503767190
                      },
                      "BTC_UAH": {
                         "buy_price": "107000",
                         "sell_price": "107790",
                         "last_trade": "107790",
                         "high": "109900",
                         "low": "105354",
                         "avg": "108167.30195869",
                         "vol": "34.94251977",
                         "vol_curr": "3770330.73968614",
                         "updated": 1503767167
                      },
                      "DASH_BTC": {
                         "buy_price": "0.08528559",
                         "sell_price": "0.08644069",
                         "last_trade": "0.086196",
                         "high": "0.093364",
                         "low": "0.07043",
                         "avg": "0.0803689",
                         "vol": "1595.2753788",
                         "vol_curr": "123.76291968",
                         "updated": 1503767189
                      },
                   },
                   "request": {
                      "uri": {
                         "protocol": "https:",
                         "slashes": true,
                         "auth": null,
                         "host": "api.exmo.",
                         "port": 443,
                         "hostname": "api.exmo.",
                         "hash": null,
                         "search": null,
                         "query": null,
                         "pathname": "/v1/ticker/",
                         "path": "/v1/ticker/",
                         "href": "https://api.exmo./v1/ticker/"
                      },
                      "method": "GET",
                      "headers": {
                         "accept": "application/json"
                      }
                  }
                }
        Object.keys(res.body).forEach((k) => {
          result= {
            mk: 'exmo',
            name: k,
            a: res.body[k].sell_price,
            b: res.body[k].buy_price,
            c: res.body[k].last_trade,
            v: res.body[k].vol,
            t: res.body[k].vol_curr,
            l: res.body[k].low,
            h: res.body[k].high,
            sn: res.body[k].updated,
          }
        });
        return result;
    });
    
    Promise.all([data()]).then((data) => {
    console.log(JSON.stringify(data, null, 3));
  })
};

exmo();

<!-- begin snippet: js hide: false console: true babel: false -->

发布评论

评论列表(0)

  1. 暂无评论