使用 npm request-promise 时如何修复奇怪的循环迭代?

How to fix strange loop iteration when using npm request-promise?

我一直在尝试使用网络抓取从网站获取一些数据到我的 NODE 应用程序中。尽管我创建的 for 循环中有奇怪的操作,但数据看起来工作正常。

我面临的问题:

  1. 迭代不是连续的。
  2. list.length 从 1 而不是 0 开始,为什么?
  3. 并非所有数据都添加到table。

所以我正在使用的代码(见下文)遍历 URL 的列表,然后我将它们添加到一个名为 options 的对象中,最后将选项传递给request-promise 函数。第一个问题是,在一次试验中,它将按顺序 1、2、0 执行,而在另一次试验中,它可能会执行 0、2、1。由于我使用 GET 请求访问服务器,我认为它需要时间来加载数据,所以我尝试使用 asyncawait 但没有用。我也试过 sleep 但还是没用。序列仍然是 unstable.

第二个问题是列表的长度不是从 0 开始,而是从 1 开始。(即 let list = ["0", "1", "2", "3"] 的长度为 4)。在 NODE 中是默认的吗?

第三个问题是,即使进行了所有迭代(即使顺序错误),有时它显示的数据也会比预期少!

const listOfJobIds = ["MTM2NDQtMTE1NzQ2LVMgMQ", "MjI3MjkwIDU", "MjI3MjIzIDU"];
let listLength = listOfJobIds.length - 1;
let options = {};

function loopJobs(listOfJobIds) {

    for(let i=0; i<listOfJobIds.length; i++){
        //Declare options for the request-promise
        options = {
            url: 'https://ec.europa.eu/eures/eures-searchengine/page/jv/id/'+listOfJobIds[i]+'?lang=en&_=1594981312724&app=2.4.1-build-2',
            json: true
        }
        
        rp(options).then(
            async (data) => {

                await getJobInformation(data, i); 
            }
        ).catch(
            (err) => {
                console.log(err);
            }
        );
    }    
}
loopJobs(listOfJobIds);

async function getJobInformation(data, i) {

    process.stdout.write('JOB: '+i+' - Loading JOB information ');

    //GET SOME DATA
    var language = data.jvProfiles[data.preferredLanguage];
    let job_id = data.id;
    process.stdout.write('. ');
    let job_vacancy_id = data.documentId;
    process.stdout.write('. ');
    let job_title = language.title;
    process.stdout.write('. ');
    let job_description = language.description;
    process.stdout.write('. ');
        
    //ADD INFORMATION IN THE TABLE
    job_table.push([
        job_id, 
        job_vacancy_id,
        job_title, 
        job_description
    ]);

    console.log("✅");
    
    if(i == listLength){
        printTable1();
    }
}

试验 1:

JOB: 0 - Loading JOB information . . . . ✅
JOB: 2 - Loading JOB information . . . . ✅
┌──────────────┬──────────────────┬────────────────────────────────────────┬──────────────────────────────────────────────────────────────────────┐       
│ Job ID       │ Job Vacancy ID   │ Job Title                              │ Job Description                                                      │       
├──────────────┼──────────────────┼────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────┤       
│ MTM2NDQtMTE… │ 13644-115746-S   │ SAP BASIS HANA Manager, Database Engi… │ Stellenangebotsbeschreibung: <br>Minimum qualifications:<br><br>- B… │       
├──────────────┼──────────────────┼────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────┤       
│ MjI3MjIzIDU  │ 227223           │ DATABASE ADMINISTRATION                │ -MANAGING DATABASES ON PREMISES AS WELL AS IN CLOUD -HANDLING MIGRA… │       
└──────────────┴──────────────────┴────────────────────────────────────────┴──────────────────────────────────────────────────────────────────────┘       
JOB: 1 - Loading JOB information . . . . ✅

试验 2:

JOB: 2 - Loading JOB information . . . . ✅
┌──────────────┬──────────────────┬────────────────────────────────────────┬──────────────────────────────────────────────────────────────────────┐
│ Job ID       │ Job Vacancy ID   │ Job Title                              │ Job Description                                                      │
├──────────────┼──────────────────┼────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────┤
│ MjI3MjIzIDU  │ 227223           │ DATABASE ADMINISTRATION                │ -MANAGING DATABASES ON PREMISES AS WELL AS IN CLOUD -HANDLING MIGRA… │
└──────────────┴──────────────────┴────────────────────────────────────────┴──────────────────────────────────────────────────────────────────────┘
JOB: 1 - Loading JOB information . . . . ✅
JOB: 0 - Loading JOB information . . . . ✅

如果您尝试对 getJobInformation() 的调用进行排序,那么您可以这样做:

async function loopJobs(listOfJobIds) {

    for (let i=0; i<listOfJobIds.length; i++){
        //Declare options for the request-promise
        let options = {
            url: 'https://ec.europa.eu/eures/eures-searchengine/page/jv/id/'+listOfJobIds[i]+'?lang=en&_=1594981312724&app=2.4.1-build-2',
            json: true
        }
        
        let data = await rp(options);
        await getJobInformation(data, i); 
    }    
    printTable1();     // I would suggest removing this call from getJobInformation()
}

loopJobs(listOfJobIds).then(() => {
    console.log("all done");
}).catch(err => {
    console.log(err);
});

注意:getJobInformation() 不是经典的异步函数。它写入有点异步的流,但函数中没有任何内容正在等待,因此你没有用它 asyncawaiting 它。