2017-10-31 9 views
0

루프 내에서 개체를 만들려고합니다. 내 aFunctionCreatesParseObjectAndSave에서구문 분석 서버에서 중복 항목 만들기

myarray=[1,1,1,1,1]; 

for (var k = 0; k < myarray.length; k++){ 
     var id = myarray[k]; 
     aFunctionCreatesParseObjectAndSave(id); 
} 

는 (ID) 기능, 나는 확인하기 위해 노력하고있어 그 i가 같은 ID로 구문 분석 객체가있는 경우. (parsequery와 함께) 만약 내가 다음, 그냥 업데이 트를 생성하지 마십시오. 그러나 객체가 없다면 생성하고 저장하십시오.

function aFunctionCreatesParseObjectAndSave(id){ 
    var query= new Parse.Query(MyParseObject); 
    query.equalTo("myId",id); 

    query.first().then(
     function(result){ 
       if(result === undefined){ 
        // there isn't entry for this id 
        //create parseObject and fill it 
        ... 
         newObject.set("id",id); 
         newObject.save(); 
       }else{ 
         // entry found for this id 
         //do update on result and save 
         ... 
         result.save(); 
       } 
     } 
    ); 

} 

내 테스트 배열 (모든 요소는 동일한 ID 임)에는 하나의 항목 만 만들어야합니다. 하지만 난 myarray.length 카운트 객체 :(내가이 문제를 해결하려면 어떻게

?

+0

한 가지주의해야 할 것은 오타가 있다는 것입니다. 'queryIqualTo ('myId ...)'하지만 다음과 같이 설정하고 있습니다 :'newObject.set ("id", id);'그래서'id'를 설정했지만'myId'를 찾고 있습니다. 그것이 일어날 때 당신은 나의 대답에서 설명 할 약속들에 대해 근본적인 문제를 가지고 있습니다. –

답변

0

약속이있다!

진짜로 짧은 대답은 당신이 아무것도 존재하는지 연속으로 다섯 번을 확인하고 있다는 것입니다 첫 번째 개체 적 저장하기 전에. 긴 답변을 지금

좋아.

귀하의 루프 기능이 물건을한다. aFunctionCreatesParseObjectAndSave를 호출하지만 그 물건을 할 수 있도록 루프는 기다리지 않습니다.을 쿼리 및 저장 그는 객체가 비동기 적이기 때문에 함수는 호출하는 쿼리가 계속 실행 되더라도 즉시 "반환"합니다.

희망, 나는 무슨 일이 일어나고 있는지 분명히 할 수 있습니다 :

  1. 내가 무엇을 내가 그 방법을 보여 드리겠습니다
  2. 에 것입니다 "증명"할 코드에 약간의 조정을 할 수 있습니다 약속의 선하심으로 그것을 행하는 것;
  3. 마지막으로 고유 ID를 원한다면 백킹 스토어에 고유 색인을 추가하십시오 (mongo?).

여기에 나열된 첫 번째 코드는 더 많거나 적은 코드와 단위 테스트, 플러스 희망에 마지막 테스트에 무슨 일이 일어나고 있는지 보여는 ....

다음
// testing boilerplate 2 lines... 
describe('my test',() => { 
    it('count', (done) => { 
    // ok, this is all "our code"   
    const MyParseObject = 'TestClass'; 

    // a function to count number of records with a given id. 
    // Importantly, this function returns a promise. 
    const count = function count(id) { 
     return new Parse.Query(MyParseObject) 
     .equalTo('myId', id) 
     .count(); // <-- count returns a promise 
    } 

    // your function with all the ...'s filled in. 
    function aFunctionCreatesParseObjectAndSave(id){ 
     var query = new Parse.Query(MyParseObject); 
     query.equalTo("myId",id); 
     query.first().then(
     function(result){ 
      if(result === undefined){ 
      // there isn't entry for this id 
      //create parseObject and fill it 
      const newObject = new Parse.Object(MyParseObject); 
      newObject.set('myId',id); 
      // you don't wait for this promise to resolve! 
      newObject.save(); 
      } else { 
      // entry found for this id 
      // do update on result and save 
      result.increment('count'); 
      // this never gets called, and is never waited on... 
      result.save(); 
      } 
     }); 
    } 

    const myarray = [1,1,1,1,1]; 

    for (var k = 0; k < myarray.length; k++){ 
     var id = myarray[k]; 
     aFunctionCreatesParseObjectAndSave(id); 
    } 

    // so what I'm doing here is waiting for 
    // 1 second, then counting the number 
    // of records with the same 'myId'. 
    // and then testing that each id in the array 
    // got a new object. 
    setTimeout(() => { 
     count(id) 
     // count will be 5 and that's one per element in myarray 
     .then(count => expect(count).toBe(myarray.length)) 
     .then(done) 
     .catch(done.fail) 
    }, 1000); // 1,000 miliseconds is one second 
    }); 
}); 

이되는 방법 I 하나의 객체 만 만들고 각 반복에서 카운터를 증가시키는 코드를 "고정"합니다.

describe('my test',() => { 
    const MyParseObject = 'TestClass'; 

    it('count', (done) => { 
    // This will call an array of functions that return promises in sequence. 
    const sequence = function sequence(tasks) { 
     return tasks.reduce((promise, task) => promise.then(() => task.call()), Promise.resolve()); 
    } 

    function aFunctionCreatesParseObjectAndSave(id){ 
     var query = new Parse.Query(MyParseObject); 
     query.equalTo("myId",id); 

     // Very important to return this promise! 
     return query.first().then(
     function(result){ 
      if(result === undefined){ 
      // there isn't an entry for this id 
      //create parseObject and fill it 
      const newObject = new Parse.Object(MyParseObject); 
      newObject.set('myId', id); 
      newObject.set('count', 1); 
      // very important to return this promise! 
      return newObject.save(); 
      } else { 
      // entry found for this id 
      //do update on result and save 
      result.increment('count'); 
      // very important to return this promise! 
      return result.save(); 
      } 
     }); 
    } 

    const myarray = [1,1,1,1,1]; 
    const promises = []; 
    for (var k = 0; k < myarray.length; k++){ 
     var id = myarray[k]; 
     // don't call the function, make an array of functions that call the functions. 
     promises.push(() => aFunctionCreatesParseObjectAndSave(id)); 
    } 

    // We have an array promises that haven't even started to run. 
    // the function sequence() will now execute each promise 
    // in the array, then wait till its done and start the next 
    // promise. 
    sequence(promises) 
     .then(() => new Parse.Query(MyParseObject).find()) 
     .then(results => { 
     // this test verifies that there is only one object now. 
     expect(results.length).toBe(1); 
     const theObj = results[0]; 
     // the count member of the object should be 5, one for each 
     // id element of 1 in 'myarray' 
     expect(theObj.get('count')).toBe(myarray.length); 
     done(); 
     }) 
     .catch(done.fail); 
    }); 
}); 

여기에서 수행 한 테스트는 nodejs 서버에서 단위 테스트를 실행하는 컨텍스트에 있습니다. 그리고 sequence 함수를 작성했습니다. "실제 환경에서"특히 브라우저에서이 코드를 실행하는 경우 bluebird와 같은 라이브러리를 사용하고 mapSeries을 사용하려고합니다.