약속의 모든 코드가 해결되기 전에 완료되기를 기다리는 방법은 무엇입니까? (하지만 조금 더 복잡함)

MrSmarty

매우 혼란스러운 질문에 대해 죄송합니다. 노드 모듈이나 라이브러리없이 웹 사이트에서 정보를 가져 오는이 코드가 있습니다. ?page=URL의 끝에서 사용하는 다른 페이지로 분리 된 사용자 목록입니다 . 페이지를 반복하고 원시 HTML을 바로 분할했습니다. 그러나 내 약속은 모든 데이터가 수집되기 전에 해결됩니다. 약속을 해결하기 전에 모든 것이 완료 될 때까지 어떻게 기다릴 수 있습니까? 나는 수많은 해결책을 시도했지만 작동하지 않는 것 같습니다. 내 목표는 하나를 사용하지 않는 것이므로 노드 패키지를 사용하도록 요청하지 마십시오. :) 친구가 정규 표현식을 도왔고 분할했습니다. 내가 사용하는 코드는 다음과 같습니다.

function getData() {
    return new Promise((resolve, reject) => {
        let final = [] //the array of users returned in the end
        const https = require("https"), url = "https://buildtheearth.net/buildteams/121/members";
        https.get(url + "?page=1", request => { //initial request, gets the number of user pages.
            let rawList = '';

            request.setEncoding("utf8"), 
            request.on("data", data => {rawList += data}), 
            request.on("end", () => {
                if(request = (request = (request = rawList.substring(rawList.indexOf('<div class="pagination">'))).substring(0, request.indexOf("</div>"))).match(/<a(.+)>(.+)<\/a>/g)) {
                    for(let t = parseInt(request[request.length - 1].match(/(\d+)(?!.*\d)/g)), a = 1; a < t + 1; a++) { //iterates through member pages
                        https.get(url + "?page=" + a, request2 => { //https request for each page of members
                            let rawList2 = '';
                            
                            request2.setEncoding('utf8'), 
                            request2.on("data", data => {rawList2 += data}), 
                            request2.on("end", () => {
                                let i = rawList2.match(/<td>(.+)<\/td>/g); //finds table in HTML
                                if (i) 
                                    for (var t = 1; t < i.length; t += 3) //iterates through rows in table
                                        console.log(i[t].replace(/<td>/g, "").replace(/<\/td>/g, "")), /* logs element to the console (for testing) */
                                        final.push(i[t].replace(/<td>/g, "").replace(/<\/td>/g, "")); //pushes element to the array that is resolved in the end
                            })
                        })
                        
                    }
                }
                resolve(final) //resolves promise returning final array, but resolves before elements are added with code above
            })
        })
    })
}

이것이 도움이된다면 정보를 얻으려는 웹 사이트가 여기 있습니다. 나는 여전히 JS를 처음 접하기 때문에 도움을 줄 수 있다면 정말 감사하겠습니다 :)

MrSmarty

내가 가진 비동기 함수로 각 작업을 돌려 결국 trycatch블록 다음과 함께 기능을 체인 .then()베이스를 들어 내가에서 영감을했다 (웹 사이트에서 데이터를 가져 오는) 에 대한 기사 중간 . 여기에 내가 데이터를 당겨하고있는 사이트이며, 여기 웹 사이트에서 데이터를 얻을 수있는 기능입니다 :

const getData = async (url) => {
    const lib = url.startsWith('https://') ? https : http;
  
    return new Promise((resolve, reject) => {
        const req = lib.get(url, res => {
            if (res.statusCode < 200 || res.statusCode >= 300) {
                return reject(new Error(`Status Code: ${res.statusCode}`));
            }

            const data = [];

            res.on('data', chunk => data.push(chunk));
            res.on('end', () => resolve(Buffer.concat(data).toString()));
        });
  
        req.on('error', reject);
        req.end();
    });
};

그런 다음 ?page=<page number>이 함수를 사용하여 페이지 수 ( URL 끝에 추가 하여 액세스 할 수 있음)를 얻었습니다 .

const pages = async () => {
    try {
        let html = await getData('https://buildtheearth.net/buildteams/121/members',);
        let pages = await (html = (html = html.substring(html.indexOf('<div class="pagination">'))).substring(0, html.indexOf("</div>"))).match(/<a(.+)>(.+)<\/a>/g)
        let pageCount = await parseInt(pages[pages.length - 1].match(/(\d+)(?!.*\d)/g))
        return pageCount
    } catch (error) {
        console.error(error);
    }
}

그런 다음 페이지 수를 사용하여 페이지를 반복하고이 함수를 사용하여 각 페이지의 HTML을 배열에 추가했습니다.

const getPages = async pageCount => {
    let returns = []
    try {
        for (page = 1; page <= pageCount; page++) {
            try {
                let pageData = await getData('https://buildtheearth.net/buildteams/121/members?page=' + page)
                returns.push(pageData)
            } catch (error) {
                return error
            }
        }
    } catch (error) {
        return error
    } finally {return returns}
}

그런 다음 각 페이지의 HTML 문자열 배열을 반복하고 필요한 멤버 목록을 반환하는이 함수를 사용하여 각각에서 필요한 데이터를 추출했습니다.

const iteratePages = async pages => {
    if (!Array.isArray(pages)) return
    try {
        let returns = []
        await pages.forEach(page => {
            let list = page.match(/<td>(.+)<\/td>/g);
            if (list)
                for (var element = 1; element < list.length; element += 3)
                    returns.push(list[element].replace(/<td>/g, "").replace(/<\/td>/g, ""));
        })
        return returns
    } catch (error) {
        return error
    }   
}

그리고 나서 필요한 배열을 얻기 위해 각각을 연결하는 문제였습니다.

pages().then(pageCount => getPages(pageCount)).then(pages => iteratePages(pages)).then(finalList => {console.log(finalList); console.log(finalList.length)})

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관