首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何通过适当的异步/等待/承诺来提高代码的速度?

如何通过适当的异步/等待/承诺来提高代码的速度?
EN

Stack Overflow用户
提问于 2019-02-21 21:42:08
回答 2查看 927关注 0票数 0

使用Node.js,我有一个任务来改进我创建的代码。此代码执行60个HTTP请求,并为此使用库。

完成所有HTTP请求并将每个请求保存到一个文件需要30秒!

据说,可以在3秒内完成这些请求,包括:

1.正确管理异步承诺

2.更智能的缓存

3.不使用集群

4.只增加一次的开销

恐怕我不知道从哪里开始,明白我能做些什么。

因此,下面的代码获得了一个由60个项组成的数组,其中每个条目都是一个HTTP请求:

代码语言:javascript
复制
const exchanges = ccxt.exchanges

这些内容进入: worker =异步函数,在代码结束时:等待Promise.all(工人)等待他们完成。

,我不知道从哪里开始,实际上可以降到3秒。如何才能提高代码的速度?

代码语言:javascript
复制
'use strict';

const ccxt  = require ('ccxt')
    , log   = require ('ololog').noLocate // npm install ololog
    , fs    = require ('fs')

    // the numWorkers constant defines the number of concurrent workers
    // those aren't really threads in terms of the async environment
    // set this to the number of cores in your CPU * 2
    // or play with this number to find a setting that works best for you
    , numWorkers = 8

;(async () => {

    // make an array of all exchanges
    const exchanges = ccxt.exchanges

        .filter (id => ![ 'cap1', 'cap2' ].includes (id))

        // instantiate each exchange and save it to the exchanges list
        .map (id => new ccxt[id] ({
            'enableRateLimit': true,
        }))

    // the worker function for each "async thread"
    const worker = async function () {

        // while the array of all exchanges is not empty
        while (exchanges.length > 0) {

            // pop one exchange from the array
            const exchange = exchanges.pop()

            // check if it has the necessary method implemented
            if (exchange.has['fetchTickers']) {

                // try to do "the work" and handle errors if any
                try {

                    // fetch the response for all tickers from the exchange
                    const tickers = await exchange.fetchTickers()

                    // make a filename from exchange id
                    const filename = '/myproject/tickers/' + exchange.id + 'Tickers.json'

                    // save the response to a file
                    fs.writeFileSync(filename, JSON.stringify({ tickers }));

                } catch (e) { } //Error
            }
        }
    }

    // create numWorkers "threads" (they aren't really threads)
    const workers = [ ... Array (numWorkers) ].map (_ => worker ())

    // wait for all of them to execute or fail
    await Promise.all (workers)

}) ()

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-02-22 00:29:33

我觉得你把事情弄得比他们需要的复杂多了。您可以在map回调中完成所有工作,然后使用Promise.all(promises)等待所有操作完成。这个过程确实比预期的“3秒”更长(在我的例子中是15秒),并且产生了很多错误(比如缺少apiToken,或者fetchTickers没有实现),但是这可能是我的环境中的一个问题(我以前从未使用过ccxt,也没有任何apiTokens)。

这是我想出的实现,希望它能帮助您满足您的需求:

代码语言:javascript
复制
const ccxt = require('ccxt');
const fs = require('fs');
const path = require('path');

(async () => {
    const start = Date.now();

    const dumps = ccxt.exchanges
        .filter((id) => !['coinmarketcap', 'theocean'].includes(id))
        .map(async (id) => {
            const Exchange = ccxt[id];
            const exchange = new Exchange({enableRateLimit: true});
            if (exchange.has['fetchTickers']) {
                try {
                    const tickers = await exchange.fetchTickers();
                    const dumpFile = path.join(__dirname, 'exchanges', `${id}-Tickers.json`);
                    await fs.promises.writeFile(dumpFile, JSON.stringify(tickers));
                } catch (e) {
                    console.error(e);
                }
            }
        });

    await Promise.all(dumps);

    const end = Date.now();
    console.log(`Done in ${(end - start) / 1000} seconds`);
})();
票数 1
EN

Stack Overflow用户

发布于 2019-02-21 23:14:02

我试着看看是否有可能更快地做到这一点。我试着把所有可能需要的记忆藏起来。在实际执行.fetchTickers()请求之前。

我从看上去的15秒下降到了9秒。但是下面的代码甚至还有一步,但是我确实收到了编译错误,并且不确定我做错了什么。

错误是:

ReferenceError: id未定义

难道id不是在“.pushed”的“exchange”对象中传递到“exchangesArray”中吗?

我试图首先将exchange对象放入数组中,所需时间如下:

代码语言:javascript
复制
var exchangesArray = [];

然后,在设置了这个"exchangesArray“之后,我尝试执行执行fetchTickers的函数:

代码语言:javascript
复制
'use strict';
const ccxt = require('ccxt');
const fs = require('fs');
const path = require('path');

//Cache some memories first
var exchangesArray = [];
(async () => {
  const allexchanges = ccxt.exchanges.filter((id) => !['coinmarketcap', 'theocean'].includes(id))
        .map(async (id) => {
            const Exchange = ccxt[id];
            const exchange = new Exchange({ enableRateLimit: true });
            if (exchange.has['fetchTickers']) {

                exchangesArray.push(exchange);
            }
        });

    await Promise.all(allexchanges);
})();

//Use cached memories to do the "fetchTickers()" as fast as possible
(async () => {
    const start = Date.now();

    const exchanges = exchangesArray;
    while (exchanges.length > 0) {

        // pop one exchange from the array
        const exchange = exchanges.pop()

        try {
            const tickers = await exchange.fetchTickers();
            const dumpFile = path.join(__dirname, 'exchanges', `${id}-Tickers.json`);
            await fs.promises.writeFile(dumpFile, JSON.stringify(tickers));
        } catch (e) {
            console.error(e);
        }

    }

    await Promise.all(exchanges);

    const end = Date.now();
    console.log(`Done in ${(end - start) / 1000} seconds`);
})();

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54816672

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档