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

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

据说可以在3秒内通过以下方式发出这些请求:

1.正确管理异步诺言

2.更智能的缓存

3.不使用集群

4.仅添加一次开销

恐怕我不确定从哪里开始了解我能做些什么。

因此,以下代码获得了一个包含60个项目的数组,其中每个项目都是一个HTTP请求:



const exchanges = ccxt.exchanges





这些代码进入:worker =异步函数,并在代码末尾:等待Promise.all(workers)等待它们完成。

我不确定从哪里开始实际可以降到3秒。如何提高此代码的速度?



'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)

}) ()

最佳答案

我认为您正在使事情变得复杂得多。您可以在map回调中完成所有工作,然后使用Promise.all(promises)等待所有操作完成。此过程确实比预期的“ 3秒”(在我的情况下为15秒)要长,并且会产生很多错误(例如缺少apiToken或未实现fetchTickers),但这可能是我的环境存在的问题(我以前从未使用过ccxt,而且我没有任何apiTokens)。

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

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`);
})();

09-20 23:46