2017-08-26 49 views
-1

我需要你的幫助,因爲我得到的問題中提到的typeError,我不知道爲什麼。 我有一個對象(即從請求,承諾回來)看起來像這樣:NodeJS:TypeError:undefined不是函數 - Promise.all - Object.keys

{ 
        "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(因爲它需要一組承諾),但正在尋找類似的解決方案。

+1

請告訴我們您正在嘗試與落得什麼輸出。 – jfriend00

+1

超過「需要重寫」是「只刪除一些代碼行」,https://pastebin.com/raw/znLHzvz7是你想要的嗎? – Federkun

+3

'Promise.all()'應該傳入一個promise數組。你正在傳遞一個永遠不會被調用的函數。對於初學者,完全刪除'Promise.all()'。 – jfriend00

回答

1

你的問題有點複雜,你的代碼被集中在一起,所以在這裏我已經分解了它。

此功能模仿您的服務器響應作爲示例向您展示如何管理承諾。

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

然後你可以簡單地調用getDatamapData,然後將結果輸出。您不希望Promise.all在這裏,因爲該方法只接受一組promise。

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

DEMO(注:這個演示使用你的解析對象,因此不會在getData中重新解析它)。

+0

你爲什麼在這裏使用承諾?顯示的任何異步操作都不會受益於承諾。如果這裏涉及到http請求,那麼無論如何它都應該在較低的級別被普遍化。 – jfriend00

+0

在問題中:「我有一個對象(從請求承諾返回)」@ jfriend00。 – Andy

+0

@ jfriend00,我不知道你評論的第二部分編輯部分是什麼意思。也許你可以澄清。 – Andy

1

正如你所看到的,你一遍又一遍地在健全循環forEach()重新分配resultreturn末只能返回最後關鍵的信息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獲取您的信息。

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]) 

這使得在 '變調' 全表更有意義。

+0

我不確定我甚至不明白你的問題lol –

+0

嘿@Nianyi Wang!感謝您的回答!我很抱歉,這是我的錯,我想我的問題不夠確切。你有邏輯,但我正在尋找一個outpout,爲每個結果迭代提供一個新的「不同的」對象。目標是將信息推送給mongodb。 – Ardzii

1

Promise.all(可迭代)它需要一個可迭代的對象,如數組或字符串。

我修改了你的代碼,它給出了輸出。 注意: - 你的代碼邏輯我沒有改變,它給你的邏輯結果。

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 -->

+0

嘿@Srinath!這是我想到的,但由於我有forEach循環,它會產生迭代的最後結果。這不是我正在尋找的。我想從每個結果迭代中生成一個「新」對象。 – Ardzii