簡體   English   中英

如何在Node.js中實現遞歸Promise調用

[英]How to achieve recursive Promise calls in Node.js

我正在調用一個API,其中每個請求只能獲取1000條記錄,我能夠使用遞歸實現這一點。

我現在正在嘗試使用Promise實現相同的目標,我對Node.js和JavaScript還是相當陌生。

我嘗試在if else塊中添加遞歸代碼,但失敗

var requestP = require('request-promise');

const option = {
    url: 'rest/api/2/search',
    json: true,
    qs: {
        //jql: "project in (FLAGPS)",
    }
}
const callback = (body) => {

    // some code
    .
    .
    .//saving records to file
    .
    //some code
    if (totlExtractedRecords < total) {  

        requestP(option, callback).auth('api-reader', token, true)
     .then(callback)
    .catch((err) => {
        console.log('Error Observed ' + err)
    })
    }
}

requestP(option).auth('api-reader', token, true)
    .then(callback)
    .catch((err) => {
        console.log('Error Observed ' + err)
    })

我想使用promise並以同步方式執行該方法,即我想等到記錄全部導出到文件並繼續執行我的代碼

我認為它能夠更好地創建自己的承諾,並簡單地解決它,當你與你的遞歸方法來實現。 這是一個簡單的示例,僅供您理解方法

 async function myRecursiveLogic(resolveMethod, ctr = 0) { // This is where you do the logic await new Promise((res) => setTimeout(res, 1000)); // wait - just for example ctr++; console.log('counter:', ctr); if (ctr === 5) { resolveMethod(); // Work done, resolve the promise } else { await myRecursiveLogic(resolveMethod, ctr); // recursion - continue work } } // Run the method with a single promise new Promise((res) => myRecursiveLogic(res)).then(r => console.log('done')); 

這是使用最新的NodeJS功能的干凈,不錯的解決方案。 遞歸函數將繼續執行,直到滿足特定條件為止(在本示例中為異步獲取一些數據)。

const sleep = require('util').promisify(setTimeout)

const recursive = async () => {
  await sleep(1000)
  const data = await getDataViaPromise() // you can replace this with request-promise

  if (!data) {
    return recursive() // call the function again
  }

  return data // job done, return the data
}

遞歸函數可以按如下方式使用:

const main = async () => {
  const data = await recursive()
  // do something here with the data
}

使用您的代碼,我將其重構如下所示。 希望對您有所幫助。

const requestP = require('request-promise');
const option = {
    url: 'rest/api/2/search',
    json: true,
    qs: {
        //jql: "project in (FLAGPS)",
    }
};

/* 
    NOTE: Add async to the function so you can udse await inside the function 
*/

const callback = async (body) => {

    // some code

    //saving records to file

    //some code

    try {
        const result = await requestP(option, callback).auth('api-reader', token, true);
        if (totlExtractedRecords < total) {
            return callback(result);
        }
        return result;
    } catch (error) {
        console.log('Error Observed ' + err);
        return error;
    }
}

使用Amir Popovich的反饋創建了此代碼

const rp = require('Request-Promise')
const fs = require('fs')

const pageSize = 200

const options = {
    url: 'https://jira.xyz.com/rest/api/2/search',
    json: true,
    qs: {
        jql: "project in (PROJECT_XYZ)",            
        maxResults: pageSize,
        startAt: 0,
        fields: '*all'
    },
    auth: {
        user: 'api-reader',
        pass: '<token>',
        sendImmediately: true
    }
}



const updateCSV = (elment) => {
    //fs.writeFileSync('issuedata.json', JSON.stringify(elment.body, undefined, 4))
}


async function getPageinatedData(resolve, reject, ctr = 0) {
    var total = 0

    await rp(options).then((body) => {
        let a = body.issues
        console.log(a)
        a.forEach(element => {
            console.log(element)
            //updateCSV(element)
        });

        total = body.total

    }).catch((error) => {
        reject(error)
        return
    })

    ctr = ctr + pageSize
    options.qs.startAt = ctr

    if (ctr >= total) {
        resolve();
    } else {
        await getPageinatedData(resolve, reject, ctr);
    }
}

new Promise((resolve, reject) => getPageinatedData(resolve, reject))
    .then(() => console.log('DONE'))
    .catch((error) => console.log('Error observed - ' + error.name + '\n' + 'Error Code - ' + error.statusCode));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM