2014-09-14 2 views
2

난 작은 내가 일하고 응용 프로그램과 내가해야 할 한 가지의 일환으로 패키지를 작성하고 엔드 포인트에서 JSON 데이터를 가져올하고 그것을 채우는 것입니다 JSON 엔드 포인트에서 서버 측 콜렉션에 채우기 서버 측 컬렉션.유성 0.9.1.1 -

서버 측 콜렉션 업데이트 기능을 Fiber, Meteor.bindEnvironment 또는 Meteor._callAsync에 넣어야한다는 오류 메시지가 표시됩니다.

내가 정확히 무엇을하는지, 언제 사용하지 않을 것인지, 사용법을 잘 모르는 지에 대해 명확하고 간결한 설명이 없기 때문에 나는 당혹 스럽다. 여기

내 패키지 파일 내의 중요한 것이 무엇인지를 살펴입니다

api.addFiles([ 
    '_src/collections.js' 
], 'server'); 

사이비 코드의 비트 :

1) Mongo.Collection 항목의 목록을 설정

2) 성공적이었다 가져올 경우 해결 약속을 반환, 내가라고 쓴 함수 httpFetch()를 사용하여 이러한 채우기 각각의 컬렉션에 대한이를 실행합니다.

3) 밑줄 each() 루프 내에서이 httpFetch 함수를 호출하여 내가 가진 각 컬렉션을 거치며 json 데이터를 가져 와서 서버 측 Mongo DB에 삽입하려고 시도합니다.

Collections.js 아래 무엇처럼 보인다. 파이버에서 삽입 기능을 래핑하면 오류 메시지가 표시되지 않지만 데이터가 DB에 삽입되지 않습니다.

/** 

* 서버 측 구성 요소는 원격 요청 * 서버 측 몽고 컬렉션을 채울 엔드 포인트를합니다. * * @class 서버 @static * */ 서버 = {

Fiber: Npm.require('fibers'), 

/** 
* Collections to be populated with content 
* 
* @property Collections 
* @type {Object} 
*/ 
Collections: { 
    staticContent: new Mongo.Collection('staticContent'), 
    pages:   new Mongo.Collection('pages'), 
    projects:  new Mongo.Collection('projects'), 
    categories:  new Mongo.Collection('categories'), 
    formations:  new Mongo.Collection('formations') 
}, 

/** 
* Server side base url for making HTTP calls 
* 
* @property baseURL 
* @type {String} 
*/ 
baseURL: 'http://localhost:3000', 

/** 
* Function to update all server side collections 
* 
* @method updateCollections() 
* @return {Object} - a resolved or rejected promise 
*/ 
updateCollections: function() { 

    var deferred = Q.defer(), 
     self = this, 
     url = '', 
     collectionsUpdated = 0; 

    _.each(self.Collections, function(collection) { 

     // collection.remove(); 
     url = self.baseURL + '/content/' + collection._name + '.json'; 

     self.httpFetch(url).then(function(result) { 

      jsonData = EJSON.parse(result.data); 

      _.each(jsonData.items, function(item) { 
       console.log('inserting item with id ', item.id); 
       self.Fiber(function() { 
        collection.update({testID: "Some random data"} 
       }); 
      }); 

      deferred.resolve({ 
       status: 'ok', 
       message: 'Collection updated from url: ' + url 
      }); 

     }).fail(function(error) { 
      return deferred.reject({ 
       status: 'error', 
       message: 'Could not update collection: ' + collection._name, 
       data: error 
      }); 
     }); 

    }); 

    return deferred.promise; 
}, 

/** 
* Function to load an endpoint from a given url 
* 
* @method httpFetch() 
* @param {String} url 
* @return {Object} - A resolved promise if the data was 
*      received or a rejected promise. 
*/ 
httpFetch: function(url) { 

    var deferred = Q.defer(); 

    HTTP.call(
     'GET', 
     url, 
     function(error, result) { 
      if(error) { 
       deferred.reject({ 
        status: 'error', 
        data: error 
       }); 
      } 
      else { 
       deferred.resolve({ 
        status: 'ok', 
        data: result.content 
       }); 
      } 
     } 
    ); 
    return deferred.promise; 
} 

};

나는 아직도이 문제에 매달 렸고, 다른 게시물을 읽으려고 전에 시도한 것에서는 여전히이 작업을 얻거나 작동하도록하는 '최상의 방법'을 파악할 수 없다. 모든.

는 2011/2012의 제안이 많이 있습니다하지만 유성 사물의 꽤 많이 깰 수 일정한 플럭스, 심지어 사소한 업데이트에 있기 때문에 나는 그들을 사용하기를 꺼려 할 것이다.

감사

답변

1

좋은 소식 :이 솔루션은 실제로 당신이 지금까지 작성한 모든 코드보다 훨씬 간단하다.

내가 파악한 바에 따르면, HTTP.get의 비동기 버전을 사용하여 약속으로 장식 된 httpFetch 함수를 작성했습니다. 그럼 당신은 전화 비동기 HTTP.get이 약속 then의 사용에 의해 계속 콜백을 도입하기 때문에 새로운 Fiber에서 컬렉션 갱신을 실행하기 위해 노력하고 있습니다.

updateCollections:function(){ 
    // we are inside a Meteor.method so this code is running inside its own Fiber 
    _.each(self.Collections, function(collection) { 
    var url=// whatever 
    // sync HTTP.get : we get the result right away (from a 
    // code writing perspective) 
    var result=HTTP.get(url); 
    // we got our result and we are still in the method Fiber : we can now 
    // safely call collection.update without the need to worry about Fiber stuff 
    }); 

당신은주의 깊게 읽어야

서버로 볼 수 있습니다 HTTP.get의 동기 버전을 사용하고 처음에해야 할 일은, 이것은 당신이 코드의 유형을 작성할 수 있습니다 HTTP 모듈에 관한 문서 : http://docs.meteor.com/#http_call

0

이제이 기능을 사용할 수 있습니다. HTTP.get()가 성공 또는 호출했을 때

"Error: Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment."

내가 콜백을 실행하려면이 httpFetch 기능을 변경 : 문제가 오류로 상승을주고 있었다 약속을 돌려 내 httpFetch 기능과 함께했다 나타납니다 오류.

이 콜백 내부에는 가져온 데이터를 구문 분석하여이를 내 컬렉션에 삽입하는 코드가 있습니다. 이것이 현재 작동중인 중요한 부분입니다.

다음은 수정 된 Collections.js 파일이며 모든 것을 설명하는 주석이 있습니다.

Server = { 

/** 
* Collections to be populated with content 
* 
* @property Collections 
* @type {Object} 
*/ 
Collections: { 
    staticContent: new Mongo.Collection('staticContent'), 
    pages:   new Mongo.Collection('pages'), 
    projects:  new Mongo.Collection('projects'), 
    categories:  new Mongo.Collection('categories'), 
    formations:  new Mongo.Collection('formations') 
}, 

/** 
* Server side base url for making HTTP calls 
* 
* @property baseURL 
* @type {String} 
*/ 
baseURL: 'http://localhost:3000', 

/** 
* Function to update all server side collections 
* 
* @method updateCollections() 
* @return {Object} - a resolved or rejected promise 
*/ 
updateCollections: function() { 

    var deferred = Q.defer(), 
     self = this, 
     collectionsUpdated = 0; 

    /** 
    * Loop through each collection, fetching its data from the json 
    * endpoint. 
    */ 
    _.each(self.Collections, function(collection) { 

     /** 
     * Clear out old collection data 
     */ 
     collection.remove({}); 

     /** 
     * URL endpoint containing json data. Note the name of the collection 
     * is also the name of the json file. They need to match. 
     */ 
     var url = self.baseURL + '/content/' + collection._name + '.json'; 

     /** 
     * Make Meteor HTTP Get using the function below. 
     */ 
     self.httpFetch(url, function(err, res) { 

      if(err) { 
       /** 
       * Reject promise if there was an error 
       */ 
       deferred.reject({ 
        status: 'error', 
        message: 'Error fetching content for url ' + url, 
        data: err 
       }); 
      } 
      else { 
       /** 
       * Populate fetched data from json endpoint 
       */ 
       var jsonData = res.content; 
        data = EJSON.parse(res.content); 

       /** 
       * Pick out and insert each item into its collection 
       */ 
       _.each(data.items, function(item) { 
        collection.insert(item); 
       }); 

       collectionsUpdated++; 

      } 

      if(collectionsUpdated === _.size(self.Collections)) { 

       /** 
       * When we have updated all collections, resovle the promise 
       */ 
       deferred.resolve({ 
        status: 'ok', 
        message: 'All collections updated', 
        data: { 
         collections: self.Collections, 
         count: collectionsUpdated 
        } 
       }); 
      } 
     }); 

    }); 

    /** 
    * Return the promise 
    */ 

    return deferred.promise; 
}, 

/** 
* Function to load an endpoint from a given url 
* 
* @method httpFetch() 
* @param {String} url 
* @param {Function} cb - Callback in the event of an error 
* @return undefined 
*/ 
httpFetch: function(url, cb) { 

    var res = HTTP.get(
     url, 
     function(error, result) { 
      cb(error, result); 
     } 
    ); 
} 

}};