简体   繁体   中英

chain async functions in node.js

I have an async function, which takes a my_url as parameter and update its value each time it runs :

function getUser(my_url) {
 var options = {url: my_url};
 request(options, function (body){
    my_url = body.url;
 });
}

I want to call this function indefinite times. For example: getUser("a") returns "b", getUser("b") return "c" and so on. What's the best practice here? I've tried making getUser() returns a promise with my_url as value, but I don't know how to call it repeatedly.

You can try something like this (I've changed URL creation a bit to demonstrate the flow with an example URL):

'use strict';

const request = require('request');

function delay(ms) {
  return new Promise((resolve) => { setTimeout(resolve, ms); });
}

function promisifiedRequest(url) {
  return new Promise((resolve, reject) => {
    request({ url }, (err, res, body) => {
      if (err) reject(err);
      else resolve(body);
    });
  });
}

(async function main() {
  try {
    let url = 'https://example.com';

    while (url !== null) {
      const body = await promisifiedRequest(url);
      url = `https://example.com?q=${
        encodeURIComponent(body.slice(0, Math.floor(Math.random() * 50)))
      }`;
      console.log(url);
      await delay(1000);
    }
  } catch (err) {
    console.error(err);
  }
})();
function getUser(my_url) {
      var options = {url: my_url};

      if(my_url == "some stop condition") return ;

      request(options, function (body){
         my_url = body.url;
      }).then( response => {
           getUser(response);
      });
  }

I'm not sure if this is what you're looking for, but here's an example using recursion and request-promise :

const rp = require('request-promise')

const url = "https://google.com"
var options = {
    uri: url
}

var count = 0

function chain(options, count) {
    const newURL = `${url}/?count=${count}`
    console.log(`Requesting ${newURL}`)
    rp(options).then(function(body) {
        console.log(`Success, body was ${body.length} bytes`)
        count = count + 1;
        if ( count < 20 ) {
            options = {
                uri: newURL
            }
            // recursion

            chain(options, count)
        }
    }).catch(function (err) {
        console.log(`An error occurred: ${err}`)
    })
}

chain(options, count)

When I run this here's the output:

Requesting https://google.com/?count=0
Success, body was 45855 bytes
Requesting https://google.com/?count=1
Success, body was 45861 bytes
Requesting https://google.com/?count=2
Success, body was 45864 bytes
Requesting https://google.com/?count=3
Success, body was 45875 bytes
Requesting https://google.com/?count=4
Success, body was 45859 bytes
Requesting https://google.com/?count=5
Success, body was 45851 bytes
Requesting https://google.com/?count=6
Success, body was 45882 bytes
Requesting https://google.com/?count=7
Success, body was 45843 bytes
Requesting https://google.com/?count=8
Success, body was 45892 bytes
Requesting https://google.com/?count=9
Requesting https://google.com/?count=9
Success, body was 45835 bytes
Requesting https://google.com/?count=10
Success, body was 45885 bytes
Requesting https://google.com/?count=11
Success, body was 45865 bytes
Requesting https://google.com/?count=12
Success, body was 45851 bytes
Requesting https://google.com/?count=13
Success, body was 45859 bytes
Requesting https://google.com/?count=14
Success, body was 45905 bytes
Requesting https://google.com/?count=15
Success, body was 45848 bytes
Requesting https://google.com/?count=16
Success, body was 45896 bytes
Requesting https://google.com/?count=17
Success, body was 45879 bytes
Requesting https://google.com/?count=18
Success, body was 45877 bytes
Requesting https://google.com/?count=19
Success, body was 45844 bytes

You could easily parse out the next URL in the response then() if you had a server that behaved that way. I put in the count to prevent infinite recursion.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM