2017-10-28 2 views
0

여러 API 호출에서 얻었지 만 배열을 만들고 무한 재귀에서 잡히는 데 문제가있는 데이터 목록을 컴파일하려고합니다.재귀 적 약속이있는 배열에 추가, 자바 스크립트

jsonToCsv() { 
    this.exportCSV().then(data => { 
    console.log('From jsonToCSV', data) 
    }) 
} 

재귀 함수

exportCSV (uidList = this.checkboxList.slice(), offset = 0) { 
    // Get query, build request 
    let request = { 
    id: 'export', 
    query: this.currentQuery.query, 
    sort: this.currentQuery.sort, 
    limit: 100, // how much data is returned 
    offset: offset // pagination value 
    } 

    return new Promise((resolve, reject) => { 

    // using Vuex to fetch data, returns an array of objects. 
    this.$store.dispatch('show/fetchQuery', request).then(data => { 
     let headerList = this.shownHeaders // an array of column id's & thier 'nice names' 
     let output = [] 
     let row, uid, header 

     // match the id's to the Data from the API call 
     for (uid = 0; uid < uidList.length; uid++) { 
     for (row = 0; row < data.length; row++) { 
      if (data[row].uid === uidList[uid]) { 
      let rowData = {} 
      uidList.splice(uid, 1) // found this id so remove from list 

      // take data from query call that we want, make objects, push them to array 
      for (header = 0; header < headerList.length; header++) { 
       let niceName = headerList[header].niceName 
       let id = headerList[header].id 
       rowData[niceName] = data[row][id] 
      } 
      output.push(rowData) 
      } 
     } 
     } 

     // Basecase 
     if (uidList.length === 0) { 
     resolve(output) 
     return 
     } 

     offset += 100 // get next 100 results from query 
     // run next recursive call 
     this.exportCSV(uidList, offset).then(newData => { 
     output.push(newData) 
     resolve(newData) 
     }) 
    }) 
    }) 

내가 쿼리가 더 호출 할 경우 I는, 그러나, 제대로 basecase을 처리하고 믿고 : 재귀 함수를 호출

기능 한 번 이상, 2 레벨의 재귀를 의미하며 최신 재귀 호출 만 리턴 값이 인쇄됩니다. 배열 출력이 덮어 쓰여집니다. 기본 코드가 충족되지 않으면 어떻게 데이터를 처리합니까? 대신 모든 녹화 호출에 새로운 출력 인스턴스를 만드는 모든 녹화 통화에서 공유

답변

0
var exportCSV = (uidList = this.checkboxList.slice(1), offset = 0) => { 
     return new Promise(function(resolveFinal){ 
        var rec = (uidListTemp = uidList, offsetTemp = offset, output = [])=>{ 
        let request = { 
        id: 'export', 
        query: this.currentQuery.query, 
        sort: this.currentQuery.sort, 
        limit: 100, // how much data is returned 
        offset: offset // pagination value 
        } 

        return new Promise((resolve, reject) => { 

        // using Vuex to fetch data, returns an array of objects. 
        this.$store.dispatch('show/fetchQuery', request).then(data => { 
         let headerList = this.shownHeaders // an array of column id's & thier 'nice names' 
         let row, uid, header 

         // match the id's to the Data from the API call 
         for (uid = 0; uid < uidList.length; uid++) { 
         for (row = 0; row < data.length; row++) { 
          if (data[row].uid === uidList[uid]) { 
          let rowData = {} 
          uidList.splice(uid, 1) // found this id so remove from list 

          // take data from query call that we want, make objects, push them to array 
          for (header = 0; header < headerList.length; header++) { 
           let niceName = headerList[header].niceName 
           let id = headerList[header].id 
           rowData[niceName] = data[row][id] 
          } 
          output.push(rowData) 
          } 
         } 
         } 

         resolve(output); 
       }).then(output=>{ 
         //base case 
         if (uidList.length === 0) { 
           resolveFinal(output); 
           return output; 
          } else { 
         offset += 100 // get next 100 results from query 
         // run next recursive call 
         rec(uidList, offset, output) 
        } 
         }); 
        }); 
        } 
        rec(); 
       }) 
      } 
  1. 사용 출력.
  2. 사용 2는 최종 응답 및 중간 응답에 대해 하나를 약속합니다.
  3. 조각 (1)
0

당신은 당신이 이미 가지고 있던 사람에게 새로운 결과를 연결할해야 일을 슬라이스로 사용되어야한다. 따라서 최종 행에서는 newData로 해결하지 않고 output.concat(newData)으로 해결합니다. 또한 push이 잘못되었습니다 ... concat이 필요합니다.

약속 생성자 반 패턴을 적용한다는 점을 언급해야합니다. 즉, 이미 사용할 수있는 약속이 있어야합니다. new Promise은 필요하지 않습니다. 여기

은 볼 수있는 방법입니다 :

exportCSV (uidList = this.checkboxList.slice(), offset = 0) { 
    // Get query, build request 
    let request = { 
    id: 'export', 
    query: this.currentQuery.query, 
    sort: this.currentQuery.sort, 
    limit: 100, // how much data is returned 
    offset: offset // pagination value 
    } 

    // using Vuex to fetch data, returns an array of objects. 
    // (don't create a new promise when can return an existing one) 
    return this.$store.dispatch('show/fetchQuery', request).then(data => { 
     // Basecase 
     if (uidList.length === 0) { 
     return []; 
     } 

     let headerList = this.shownHeaders // an array of column id's & thier 'nice names' 
     let output = [] 
     let row, uid, header 

     // match the id's to the Data from the API call 
     for (uid = 0; uid < uidList.length; uid++) { 
     for (row = 0; row < data.length; row++) { 
      if (data[row].uid === uidList[uid]) { 
      let rowData = {} 
      uidList.splice(uid, 1) // found this id so remove from list 

      // take data from query call that we want, make objects, push them to array 
      for (header = 0; header < headerList.length; header++) { 
       let niceName = headerList[header].niceName 
       let id = headerList[header].id 
       rowData[niceName] = data[row][id] 
      } 
      output.push(rowData); 
      // Probably you can now break out of this loop as you 
      // will not expect a second match 
      break; 
      } 
     } 
     } 

     // run next recursive call, return the promise 
     return this.exportCSV(uidList, offset + 100).then(newData => { 
     // append to previous results 
     return output.concat(newData); 
     }) 
    }) 
}