2014-09-04 129 views
5

我有一個Meteor方法包裹一個http.get。我試圖將該http.get的結果返回到方法的返回中,以便在調用方法時可以使用結果。
雖然我不能讓它工作。返回Meteor.http結果方法

這裏是我的代碼:

(在共享文件夾)

Meteor.methods({ 
    getWeather: function(zip) { 
     console.log('getting weather'); 
     var credentials = { 
      client_id: "string", 
      client_secret: "otherstring" 
     } 

     var zipcode = zip; 

     var weatherUrl = "http://api.aerisapi.com/places/postalcodes/" + zipcode + "?client_id=" + credentials.client_id + "&client_secret=" + credentials.client_secret; 

     weather = Meteor.http.get(weatherUrl, function (error, result) { 
      if(error) { 
       console.log('http get FAILED!'); 
      } 
      else { 
       console.log('http get SUCCES'); 
       if (result.statusCode === 200) { 
        console.log('Status code = 200!'); 
        console.log(result.content); 

        return result.content; 
       } 
      } 
     }); 
     return weather; 
    } 
}); 

出於某種原因,儘管它們的存在和HTTP調用工作這並不返回結果的console.log (result.content);的確記錄了結果。

(客戶端文件夾)

Meteor.call('getWeather', somezipcode, function(error, results) { 
    if (error) 
     return alert(error.reason); 

    Session.set('weatherResults', results); 
    }); 

當然在這裏,會話變量最終被空。
(請注意,這部分代碼似乎要被罰款,因爲它返回適當的,如果我硬編碼在該方法中一些虛擬字符串返回。)

幫助?

回答

14

在你的例子中Meteor.http.get是異步執行的。

See docs

HTTP.call(方法,URL [,選項] [,的AsyncCallback])

在服務器上,該功能可以運行同步或異步 。如果省略了回調,它將同步運行,並且一旦請求成功完成,結果將返回到 。如果 請求未成功,錯誤被移除的AsyncCallback拋出

切換到同步模式:

try { 
    var result = HTTP.get(weatherUrl); 
    var weather = result.content; 
} catch(e) { 
    console.log("Cannot get weather data...", e); 
} 
+0

這是爲我做的,謝謝。 – oliv23 2014-09-29 16:04:26

+0

這怎麼能在客戶端上實現? – janjackson 2018-02-15 03:36:23

2

庫巴Wyrobek是正確的,但你也仍然可以撥打HTTP.get異步和使用未來停止返回,直到get方法作出了迴應:

var Future = Npm.require('fibers/future'); 

Meteor.methods({ 
    getWeather: function(zip) { 
     console.log('getting weather'); 
     var weather = new Future(); 
     var credentials = { 
      client_id: "string", 
      client_secret: "otherstring" 
     } 

     var zipcode = zip; 

     var weatherUrl = "http://api.aerisapi.com/places/postalcodes/" + zipcode + "?client_id=" + credentials.client_id + "&client_secret=" + credentials.client_secret; 

     HTTP.get(weatherUrl, function (error, result) { 
      if(error) { 
       console.log('http get FAILED!'); 
       weather.throw(error); 
      } 
      else { 
       console.log('http get SUCCES'); 
       if (result.statusCode === 200) { 
        console.log('Status code = 200!'); 
        console.log(result.content); 

        weather.return(result); 
       } 
      } 
     }); 
     weather.wait(); 
    } 
}); 

有沒有真正太多的優勢,以這種方法在同步在這種情況下,如果你曾經在服務器上做過某些事情,可以從異步運行的HTTP調用中獲益(因此不會阻塞方法中的其餘代碼),但是仍然需要等待該方法可以返回該調用,那麼這是正確的解決方案。一個例子就是你需要執行多個非應急get,如果同步執行,所有人都必須等待對方一個接一個地返回。

更多here

+0

Is var Future = Npm.require('fibers/future');只有服務器的東西?我如何將這個添加到我的Meteor項目中?我得到'Npm未定義'錯誤 – janjackson 2018-02-15 03:41:50

0

有時候異步調用更可取。你可以使用異步/等待語法,你需要promisify HTTP.get。該流星test方法

import { Meteor } from 'meteor/meteor'; 
import { HTTP } from 'meteor/http'; 

const httpGetAsync = (url, options) => 
    new Promise((resolve, reject) => { 
     HTTP.get(url, options, (err, result) => { 
      if (err) { 
       reject(err); 
      } else { 
       resolve(result); 
      } 
     }); 
    }); 

Meteor.methods({ 
    async 'test'({ url, options }) { 
     try { 
      const response = await httpGetAsync(url, options); 
      return response; 
     } catch (ex) { 
      throw new Meteor.Error('some-error', 'An error has happened'); 
     } 
    }, 
}); 

通知標記爲async。這允許在其中使用await運算符,該方法調用返回Promise。在返回的承諾解決之前,將不會執行await之後的代碼行。如果承諾被拒絕,catch塊將被執行。