繁体   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