简体   繁体   English

如何在nodejs中结合同步和异步功能

[英]how to combine sync and async function in nodejs

I have problems with the synchronous and asynchronous functions on NodeJS, here is my problem,我在 NodeJS 上的同步和异步函数有问题,这是我的问题,

I have 4 functions, a global variable (users), and a rendering function to have the html page.我有 4 个函数、一个全局变量(用户)和一个呈现 html 页面的函数。

the scarper1 and scarper2 function can be performed asynchronously, they scarpe a website and fill in the global user variable, and the data_selector1 cannot be done unless scarper1 has done the same for data_selector2 with the scarper2 functions. Scarper1 和 Scarper2 函数可以异步执行,它们对网站进行爬取并填充全局用户变量,而 data_selector1 无法完成,除非 Scarper1 使用 Scarper2 函数对 data_selector2 执行相同操作。

1-I need that scarper1 and scarper2 work asynchronously and fill the available users, and only render the HTML page if the 2 scarpers have finished their work. 1-我需要使 Scarper1 和 Scarper2 异步工作并填充可用用户,并且仅在 2 个 Scarper 完成工作后才呈现 HTML 页面。

2-I need an animation to be displayed in the browser during the drilling process, how can I do this 2-我需要在钻孔过程中在浏览器中显示动画,我该怎么做

Here is what I tried ..这是我尝试过的..

var express = require('express');
var request = require('request');
var cheerio = require('cheerio');
var fs = require('fs');
var router = express.Router();

 /*  globale variable to populate */

    var users = { 
                'name':null,
                'age':null,


            };

//function of scarping link1

function scarper1(callback){
    console.log("-------------scarper---------");
    var url = 'link1';

request(
  {
    method: 'GET',
    url: 'http://api.myscarperwebservice.com/?url=' + url,
    headers: {
      Accept: 'application/json',
    },
  },
  function(error, response, body) {
    if (error) throw error;
    // call the data-selector1 after scarper are finish rendering
    data_selector1(body);




  }
);


}

//function of scarping link2
function scarper2(callback){
  console.log("-------------scarper2---------");
  var url = 'link2';

request(
  {
    method: 'GET',
    url: 'http://api.myscarperwebservice.com/?url=' + url,
    headers: {
      Accept: 'application/json',
    },
  },
   function(error, response, body) {
    if (error) throw error;
    // call the data-selector2 after scarper are finish rendering
    data_selector2(body);




  }
);


}


function data_selector1(body)
{
console.log("-------------data-selector---------");
  const $ = cheerio.load(body);
  $("div[class='.user']").each(function(i,elem){


            users['name'] =$(elem).find('span[class=".name]').text();

            users['age'] =$(elem).find('span[class=".age]').text();


  });

}

function data_selector2(body)
{
console.log("-------------data-selector2---------");
  const $ = cheerio.load(body);
  $("ul[class='.user']").each(function(i,elem){


        users['name'] =$(elem).find('li[class=".name]').text();

        users['age'] =$(elem).find('li[class=".age]').text();


  });

}




/* GET home page. */

router.post('/recherche', function(req, res, next) {
   // i dont know how to make it here to say that scarper1 and scarper2 can be executed async and to render page after that the two scarper are finished 
   // and while scarper are working to display animation in the client
    scarper1(function(results){
        console.log(results);res.render('rechercher', { title: 'Express' });

    });



});

You can use promise.all() to do that but before you can use it, you need to promisify your functions:您可以使用promise.all()来做到这一点,但在使用它之前,您需要承诺您的函数:

function scarper1(callback) {
    return new Promise((resolve, reject) => {
        console.log("-------------scarper---------");
        var url = 'link1';

        request(
            {
                method: 'GET',
                url: 'http://api.myscarperwebservice.com/?url=' + url,
                headers: {
                    Accept: 'application/json',
                },
            },
            function (error, response, body) {
                if (error) reject(error);
                // call the data-selector1 after scarper are finish rendering
                data_selector1(body);
                resolve('Done successfully');
            }
        );
    });
}

function scarper2(callback) {
    return new Promise((resolve, reject) => {
        console.log("-------------scarper2---------");
        var url = 'link2';
        request(
            {
                method: 'GET',
                url: 'http://api.myscarperwebservice.com/?url=' + url,
                headers: {
                    Accept: 'application/json',
                },
            },
            function (error, response, body) {
                if (error) reject(error);
                // call the data-selector2 after scarper are finish rendering
                data_selector2(body);
                resolve('Done successfully');
            }
        );
    });
}

let scarper1 = scarper1(function(results){
    console.log(results);res.render('rechercher', { title: 'Express' });

});
let scarper2 = scarper2(function(results){
    console.log(results);res.render('rechercher', { title: 'Express' });

});

Promise.all([scarper1, scarper2]).then(function(values) {
    console.log(values);
});

For more about promise.all check this docs.有关promise.all 的更多信息,请查看此文档。

An even better approach is using async.eachLimit() to loop through requests (asynchronously) but first you need to install async package then merge both scraper functions:更好的方法是使用async.eachLimit()来循环请求(异步),但首先您需要安装async包,然后合并两个刮刀函数:

const async = require("async");
let urls = [
    'link1',
    'link2'
]
async.eachLimit(urls, 2, (url) => {
    console.log("-------------scarper---------");
    request(
        {
            method: 'GET',
            url: 'http://api.myscarperwebservice.com/?url=' + url,
            headers: {
                Accept: 'application/json',
            },
        },
        function (error, response, body) {
            if (error) reject(error);
            // call the data-selector1 after scarper are finish rendering
            if(url == 'link1')
                data_selector1(body);
            else
                data_selector2(body);

            resolve('Done successfully');
        }
    );
}, (err) => {
    console.log("Finished all urls")
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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