如何在nodejs中结合同步和异步功能
Posted
技术标签:
【中文标题】如何在nodejs中结合同步和异步功能【英文标题】:how to combine sync and async function in nodejs 【发布时间】:2020-04-08 03:44:57 【问题描述】:我在 NodeJS 上的同步和异步函数有问题,这是我的问题,
我有 4 个函数、一个全局变量(用户)和一个渲染函数来生成 html 页面。
scraper1和scraper2函数可以异步执行,它们抓取一个网站并填写全局用户变量,data_selector1不能完成,除非scraper1用scraper2函数对data_selector2做了同样的事情。
1-我需要scraper1 和scraper2 异步工作并填充可用用户,并且仅在2 个scraper 完成工作后才呈现HTML 页面。
2-我需要在钻孔过程中在浏览器中显示动画,我该怎么做
这是我尝试过的..
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 scraping link1
function scarper1(callback)
console.log("-------------scraper---------");
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 scraper are finish rendering
data_selector1(body);
);
//function of scraping link2
function scarper2(callback)
console.log("-------------scraper2---------");
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 scraper 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 scraper1 and scraper2 can be executed async and to render page after that the two scraper are finished
// and while scraper are working to display animation in the client
scarper1(function(results)
console.log(results);res.render('rechercher', title: 'Express' );
);
);
【问题讨论】:
LOL Scarper 是逃跑的意思。你的意思是刮刀。 【参考方案1】:您可以使用promise.all()
来执行此操作,但在使用它之前,您需要承诺您的功能:
function scarper1(callback)
return new Promise((resolve, reject) =>
console.log("-------------scraper---------");
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 scraper are finish rendering
data_selector1(body);
resolve('Done successfully');
);
);
function scarper2(callback)
return new Promise((resolve, reject) =>
console.log("-------------scraper2---------");
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 scraper 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);
);
有关promise.all 的更多信息,请查看此文档。
更好的方法是使用async.eachLimit()
循环请求(异步),但首先您需要安装async 包,然后合并两个scraper 函数:
const async = require("async");
let urls = [
'link1',
'link2'
]
async.eachLimit(urls, 2, (url) =>
console.log("-------------scraper---------");
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 scraper are finish rendering
if(url == 'link1')
data_selector1(body);
else
data_selector2(body);
resolve('Done successfully');
);
, (err) =>
console.log("Finished all urls")
);
【讨论】:
以上是关于如何在nodejs中结合同步和异步功能的主要内容,如果未能解决你的问题,请参考以下文章