在 coinbase-api 回调函数中使用 node.js for 循环索引

Using node.js for-loop index in a coinbase-api callback function

我是 node.js 的新手,我正在尝试制作一个简单的脚本,它将连接到 coinbase-api 并获取 MARKET 数组中定义的任何市场的当前价格。

我遇到的问题是遍历数组的 for 循环是异步的,回调函数没有获得正确的数组索引值。

我发现的两个主要解决方案是使用承诺或强制循环等待。我认为我需要使用 promises 而不是强制 for 循环等待,但老实说我未能以任何一种方式实施解决方案。我已经找到了可能的承诺示例,但我似乎无法弄清楚如何将它们实现到我的脚本中。如果有任何帮助,我将不胜感激。

const coinbaseModule = require('coinbase-pro');

const COINBASE_URI = 'https://api-public.sandbox.pro.coinbase.com';

// const MARKET = ['BTC-USD'];
const MARKET = ['BTC-USD', 'ETH-BTC'];

let askPrice = [null, null];

let averagePrice = [null, null];

let tickerCount = null;

const getCallback = (error, response, data) => 
{   
    if (error)
        return console.log(error);

    if ((data!=null) && (data.ask!=null) && (data.time!=null))
    {
        askPrice[tickerCount] = parseFloat(data.ask);
        
        if (averagePrice[tickerCount]===null)
        {
            averagePrice[tickerCount] = askPrice[tickerCount];
            console.log(MARKET[tickerCount] + " ask price: " + askPrice[tickerCount].toFixed(6));
        }
        else
        {   
            averagePrice[tickerCount] = (averagePrice[tickerCount] * 1000 + askPrice[tickerCount]) / 1001;
            console.log(MARKET[tickerCount] + " ask price: " + askPrice[tickerCount].toFixed(6) + " average price: "+ averagePrice[tickerCount].toFixed(6));
        }
    }
}

setInterval(() => 
{
    console.log('\n');
    publicClient = new coinbaseModule.PublicClient(COINBASE_URI); 

    for (tickerCount = 0; tickerCount < MARKET.length; tickerCount++) 
    {
        publicClient.getProductTicker(MARKET[tickerCount], getCallback);
    }

}, 10000);

我能够通过 Mozilla 开发人员网络上的有用示例通过反复试验弄清楚如何使用 promises。我确定我犯了一些错误,但至少它现在正在工作。另一个小好处是我能够删除全局。

const coinbaseModule = require('coinbase-pro');

const COINBASE_URI = 'https://api-public.sandbox.pro.coinbase.com';

// const MARKET = ['BTC-USD'];
const MARKET = ['BTC-USD', 'ETH-BTC'];

let askPrice = [null, null];

let averagePrice = [null, null];

function getProductTicker(tickerCount) { 
  return new Promise(resolve => {
    publicClient.getProductTicker(MARKET[tickerCount],function callback(error, response, data){
        if (error)
            return console.log(error);

        if ((data!=null) && (data.ask!=null) && (data.time!=null))
        {
            askPrice[tickerCount] = parseFloat(data.ask);
            
            if (averagePrice[tickerCount]===null)
            {
                averagePrice[tickerCount] = askPrice[tickerCount];
                console.log(MARKET[tickerCount] + " ask price: " + askPrice[tickerCount].toFixed(6));
            }
            else
            {   
                averagePrice[tickerCount] = (averagePrice[tickerCount] * 1000 + askPrice[tickerCount]) / 1001;
                console.log(MARKET[tickerCount] + " ask price: " + askPrice[tickerCount].toFixed(6) + " average price: "+ averagePrice[tickerCount].toFixed(6));
            }
        resolve();
        }
    });
  });
}

setInterval( async () => 
{
    console.log('\n');
    publicClient = new coinbaseModule.PublicClient(COINBASE_URI); 

    for (var tickerCount = 0; tickerCount < MARKET.length; tickerCount++) 
    {
        await getProductTicker(tickerCount);
    }
}, 10000);