我需要你的帮助,因为我在问题中提到了typeError,我不确定为什么。 我有一个对象(来自请求 - 承诺),看起来像这样:
{
"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.com",
"port": 443,
"hostname": "api.exmo.com",
"hash": null,
"search": null,
"query": null,
"pathname": "/v1/ticker/",
"path": "/v1/ticker/",
"href": "https://api.exmo.com/v1/ticker/"
},
"method": "GET",
"headers": {
"accept": "application/json"
}
}
}
正如您所看到的,body
有多个对象,我的目标是在每个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;
但由于某种原因,它不起作用......我觉得我没有正确使用Promise.all?
这是我的完整测试代码(它会重现错误):
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.com",
"port": 443,
"hostname": "api.exmo.com",
"hash": null,
"search": null,
"query": null,
"pathname": "/v1/ticker/",
"path": "/v1/ticker/",
"href": "https://api.exmo.com/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();
先感谢大家的帮助!
*****编辑*****:[试图澄清]我的目标是每次迭代forEach获得一个对象。最终,这些对象中的每一个都将进入mongo数据库。 我正在错误地使用Promise.all(因为它需要一组承诺)但是正在寻找类似的解决方案。
答案 0 :(得分:2)
你的问题很复杂,因为你的代码全都集中在一起,所以在这里我把它拆分了。
此功能模仿您的服务器响应作为示例,向您展示如何管理承诺。
function getData() {
return new Promise((resolve, reject) => {
// Parse the returned data
resolve(JSON.parse(res));
});
}
然后您需要转换数据。在这里,您可以使用map
来迭代obj而不是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
}
});
}
然后,您只需致电getData
,mapData
,然后输出结果即可。你不希望Promise.all
在这里,因为该方法只接受一系列承诺。
getData()
.then(mapData)
.then(data => console.log(JSON.stringify(data, null, 3)));
DEMO (n.b.此演示使用您已解析的obj,因此不会在getData
中重新解析它。)
答案 1 :(得分:1)
正如您所看到的,您在健全的循环result
中反复重新分配forEach()
,最后的return
只能返回最后一个密钥的信息在body
你需要做的是将所有值都放在一个数组中(可能是?)。
或者以更简单的方式:转置整个表格
因此,你必须在第一时间宣布一堆Array
:
// 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]))
);
现在,您可以通过result
的索引轻松获取您的信息。
如果您想按原始名称对其进行索引,可以先将
result
初始化为一堆Object
,然后使用name
代替内部push()
直接forEach()
。
Object.keys(res.body[name]).forEach(k => result[k][name] = res.body[name][k])
这对于转置'更有意义。整个表格。
答案 2 :(得分:1)
Promise.all(iterable)它接受一个可迭代的对象,如Array或String。
我修改了你的代码,它提供了输出。 注意: - 我的代码逻辑没有改变,它将结果作为你的逻辑。
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.com",
"port": 443,
"hostname": "api.exmo.com",
"hash": null,
"search": null,
"query": null,
"pathname": "/v1/ticker/",
"path": "/v1/ticker/",
"href": "https://api.exmo.com/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 -->
&#13;