2017-10-27 6 views
0

cheerio의 라이브러리 요청 기능 이외의 변수에 액세스 할 때 문제가 있습니다. 여기 요청 변수 외의 변수 액세스

내 코드는 더 나은 이해를 위해 단순화 :
var fullDragonInfo = {}; 

dragonsInfo.forEach(dragon => { 

    request(`url=${dragon.name}`, function (error, response, html) { 
     if (!error && response.statusCode == 200) { 

      var $ = cheerio.load(html); 

      $('tr').each(function (i) { 
       let childrenElement = $(this).children('td').children('font'); 

       breedingList.push({ 
        'parent_1': { 
         'name': childrenElement.eq(0).text(), 
         'color': childrenElement.eq(0).attr('color') 
        }, 
        'parent_2': { 
         'name': childrenElement.eq(1).text(), 
         'color': childrenElement.eq(1).attr('color') 
        }, 
        'Tokens': childrenElement.last().text() 
       }); 

      }); 

      Object.assign(fullDragonInfo, { 
       [dragon.name]: { 
        'type': dragon.type, 
        'tier': dragon.tier, 
        'class': dragon.class, 
        'breedable_level': dragon.breedable_level, 
        'breeds_combination': breedingList 
       } 
      }); 
     } 
    }); 
}); 

fs.writeFile("finalData.json", JSON.stringify(fullDragonInfo)); 

그래서 내 출력 파일 finalData.json 빈 객체를 보이고있다. 하지만 콜백 함수 내부에 콘솔 로그를 작성하면 데이터가 여기에 있습니다.

그래서 문제는 내가 콜백 외부에서 내 변수에 액세스 할 수 없다는 가정이지만 어떻게 할 수 있는지에 대한 단서가 없습니다.

답변

1

요청이 비동기 적으로 발생하지만 파일을 동 기적으로 쓰면 요청이 반환되기 전에 기록됩니다. 파일을 작성하기 전에 요청이 완료 될 때까지 기다려야합니다.

약속을 사용할 수 있다면 더 좋을 것입니다. 그것은 지금처럼 그러나 당신의 요청을 계산하는 코드에 덜 수정을 포함합니다 : 각 당신이 만드는 요청 카운트 업, 다음 카운트 당신이 응답을받을 때마다 제거함으로써

var fullDragonInfo = {}; 
var callbackCount = 0; 

dragonsInfo.forEach(dragon => { 

    callbackCount++; 

    request(`url=${dragon.name}`, function (error, response, html) { 

     callbackCount--; 

     if (!error && response.statusCode == 200) { 

      var $ = cheerio.load(html); 

      $('tr').each(function (i) { 
       let childrenElement = $(this).children('td').children('font'); 

       breedingList.push({ 
        'parent_1': { 
         'name': childrenElement.eq(0).text(), 
         'color': childrenElement.eq(0).attr('color') 
        }, 
        'parent_2': { 
         'name': childrenElement.eq(1).text(), 
         'color': childrenElement.eq(1).attr('color') 
        }, 
        'Tokens': childrenElement.last().text() 
       }); 

      }); 

      Object.assign(fullDragonInfo, { 
       [dragon.name]: { 
        'type': dragon.type, 
        'tier': dragon.tier, 
        'class': dragon.class, 
        'breedable_level': dragon.breedable_level, 
        'breeds_combination': breedingList 
       } 
      }); 
     } 

     if (callbackCount === 0) { 
      fs.writeFile("finalData.json", JSON.stringify(fullDragonInfo)); 
     } 
    }); 
}); 

, 당신은 알게 될 경우 그 카운트가 다시 0이면 모든 요청이 완료되어야합니다. 따라서 각 요청이 끝날 때 마지막으로 완료되었는지 확인하고, 그렇다면 파일에 데이터를 쓰는 것이 안전합니다.