多次调用异步函数 [英] Calling async function multiple times

查看:52
本文介绍了多次调用异步函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有一个方法,我想在循环中多次调用。这是函数:

So I have a method, which I want to call multiple times in a loop. This is the function:

function PageSpeedCall(callback) {
    var pagespeedCall = `https://www.googleapis.com/pagespeedonline/v4/runPagespeed?url=https://${websites[0]}&strategy=mobile&key=${keys.pageSpeed}`;
    // second call
    var results = '';
    https.get(pagespeedCall, resource => {
        resource.setEncoding('utf8');
        resource.on('data', data => {
            results += data;
        });
        resource.on('end', () => {
            callback(null, results);
        });
        resource.on('error', err => {
            callback(err);
        });
    });
    // callback(null, );
}

如您所见,这是一个调用PageSpeed API的异步函数。然后它得到响应,感谢回调并在视图中呈现它。现在我如何让它在for / while循环中工作?例如

As you see this is an async function that calls the PageSpeed API. It then gets the response thanks to the callback and renders it in the view. Now how do I get this to be work in a for/while loop? For example

function PageSpeedCall(websites, i, callback) {
    var pagespeedCall = `https://www.googleapis.com/pagespeedonline/v4/runPagespeed?url=https://${websites[i]}&strategy=mobile&key=${keys.pageSpeed}`;
    // second call
    var results = '';
    https.get(pagespeedCall, resource => {
        resource.setEncoding('utf8');
        resource.on('data', data => {
            results += data;
        });
        resource.on('end', () => {
            callback(null, results);
        });
        resource.on('error', err => {
            callback(err);
        });
    });
    // callback(null, );
}

var websites = ['google.com','facebook.com','stackoverflow.com'];
for (let i = 0; i < websites.length; i++) {
    PageSpeedCall(websites, i);
}

我想为每个网站获取一个raport。数组的长度将根据用户的用途而变化。

I want to get a raport for each of these sites. The length of the array will change depending on what the user does.

我使用 async.parallel 来调用像这样的函数:

I am using async.parallel to call the functions like this:

let freeReportCalls = [PageSpeedCall, MozCall, AlexaCall];

async.parallel(freeReportCalls, (err, results) => {
    if (err) {
        console.log(err);
    } else {
        res.render('reports/report', {
            title: 'Report',
            // bw: JSON.parse(results[0]),
            ps: JSON.parse(results[0]),
            moz: JSON.parse(results[1]),
            // pst: results[0],
            // mozt: results[1],
            // bw: results[1],
            al: JSON.parse(results[2]),
            user: req.user,
        });
    }
});

我试图使用承诺链,但由于某种原因,我不能把它放在我脑海里。这是我的尝试。

I tried to use promise chaining, but for some reason I cannot put it together in my head. This is my attempt.

return Promise.all([PageSpeedCall,MozCall,AlexaCall]).then(([ps,mz,al]) => {
    if (awaiting != null)
        var areAwaiting = true;
    res.render('admin/', {
        title: 'Report',
        // bw: JSON.parse(results[0]),
        ps: JSON.parse(results[0]),
        moz: JSON.parse(results[1]),
        // pst: results[0],
        // mozt: results[1],
        // bw: results[1],
        al: JSON.parse(results[2]),
        user: req.user,
    });
}).catch(e => {
    console.error(e)
});

我试过这样做:

return Promise.all([for(let i = 0;i < websites.length;i++){PageSpeedCall(websites, i)}, MozCall, AlexaCall]).
then(([ps, mz, al]) => {
    if (awaiting != null)
        var areAwaiting = true;
    res.render('admin/', {
        title: 'Report',
        // bw: JSON.parse(results[0]),
        ps: JSON.parse(results[0]),
        moz: JSON.parse(results[1]),
        // pst: results[0],
        // mozt: results[1],
        // bw: results[1],
        al: JSON.parse(results[2]),
        user: req.user,
    });
}).catch(e => {
    console.error(e)
});

但是节点只是说它很蠢。

But node just said it's stupid.

如果我不想将网站和迭代器传递给函数,这将有效。知道如何解决这个问题吗?

And this would work if I didn't want to pass the websites and the iterator into the functions. Any idea how to solve this?

回顾一下。到目前为止,这些功能适用于单个网站。我希望他们为一系列网站工作。

To recap. So far the functions work for single websites. I'd like them to work for an array of websites.

我基本上不确定如何调用它们,以及如何返回响应。

I'm basically not sure how to call them, and how to return the responses.

推荐答案

如果使用 fetch async /,这会容易得多await

const fetch = require('node-fetch');

async function PageSpeedCall(website) {
    const pagespeedCall = `https://www.googleapis.com/pagespeedonline/v4/runPagespeed?url=https://${website}&strategy=mobile&key=${keys.pageSpeed}`;
    const result = await fetch(pagespeeddCall);
    return await result.json();
}


async function callAllSites (websites) {
  const results = [];
  for (const website of websites) {
    results.push(await PageSpeedCall(website));
  }
  return results;
}

callAllSites(['google.com','facebook.com','stackoverflow.com'])
  .then(results => console.log(results))
  .error(error => console.error(error));

Promise.all

Which is better with a Promise.all

async function callAllSites (websites) {
  return await Promise.all(websites.map(website => PageSpeedCall(website));
}

这篇关于多次调用异步函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆