更改API调用后,React脚本停止工作



我有一个脚本,它从React调用API,然后触发电子邮件通知功能。

我把它的一部分改为调用整个参数数组,而不是一个接一个地调用一个参数。

这是更改前的部分(正在工作的部分(。控制台日志显示了正确的响应,我也收到了电子邮件通知。

const getApiData = () => {
const apiCall = (symbol) => {
return `https://min-api.cryptocompare.com/data/pricemulti?fsyms=${symbol}&tsyms=USD&api_key=API-KEY-HERE`
}
const MAX_CHARACKTERS = 300
let bucketArray = ['']
for (let i=0; i < assets.length - 1; i += 1) {
const symbol = `${bucketArray[bucketArray.length - 1]},${assets[i]}`
if (i === 0) {
bucketArray[0] = assets[i]
continue
}
if (symbol.length < MAX_CHARACKTERS) {
bucketArray[bucketArray.length - 1] = symbol
} else {
bucketArray[bucketArray.length] = assets[i]
}
}
const getData = () => {
Promise.all(
bucketArray.map(req => {
return axios(apiCall(req))
.then(({ data }) => data)
})
).then((data) => setDataApi(data))
}
getData()
};

这是一个有问题的问题。

const getApiData = () => {
const getString = symbol =>
`https://min-api.cryptocompare.com/data/pricemulti?fsyms=${symbol}&tsyms=USD&api_key=API-KEY-HERE`;
function getAxious(id) {
const url = getString(id);
return axios.get(url);
}
const BUCKET_SIZE = 150;
const bucketArray = assets.reduce(
(arr, rec) => {
if (arr[arr.length - 1].length < BUCKET_SIZE) {
arr[arr.length - 1] = [...arr[arr.length - 1], rec];
return arr;
}
return [...arr, [rec]];
},
[[]]
);
bucketArray
.reduce((acc, rec) => {
return acc.then(results => {
return Promise.all(
rec.map(item =>
getAxious(item).then(({ data }) => {
return {
Symbol: item,
Open: data
};        
})
)
).then(x => {
return [...x, ...results];
});
});
}, 
Promise.resolve([]))
.then(res => {
setDataApi(res);
});
};

在控制台中,我收到空数组-[],没有显示错误,但电子邮件通知也停止工作。

我正在更改代码,因为我需要在一次调用中从API调用整个数组。在我给一个又一个symbol打电话之前。

控制台没有显示正确的响应,我做错了什么?

EDIT1

这是bucketArray值

const assets = ['ADA','KAVA','DOGE'];

我不能完全理解,但我认为您希望将所有结果收集在一起,并使用setDataApi将其设置为数据。

检查下面的代码,让我知道它是否有帮助:

async function getApiData() {
const getString = (arr) =>
`https://min-api.cryptocompare.com/data/pricemulti?fsyms=${arr.join(
","
)}&tsyms=USD&api_key=API_KEY`;
function getAxious(arr) {
const url = getString(arr);
return axios.get(url);
}
const BUCKET_SIZE = 150;
const bucketArray = assets.reduce(
(arr, rec) => {
if (arr[arr.length - 1].length < BUCKET_SIZE) {
arr[arr.length - 1] = [...arr[arr.length - 1], rec];
return arr;
}
return [...arr, [rec]];
},
[[]]
);
const res = await getAxious(bucketArray);
console.log("res", res);
return res;
// after this you can set  setDataApi(res);
}
// keep this useEffect sepearate
const [timer, setTimer] = useState(null);
useEffect(() => {
async function getApiDatahandler() {
const res = await getApiData();
console.log(res);
const timerId = setTimeout(() => {
getApiDatahandler();
}, 1000 * 60);
setTimer(timerId);
setDataApi(res)
// set the data setDataApi(res);
}
getApiDatahandler();
return () => {
window.clearTimeout(timer);
};
}, []);
// useEffect(() => {
//     const timerId = setTimeout(() => {
//       getApiData();
//     }, 1000 * 60);
// }, [])

检查此代码笔以获得可能的解决方案。https://codepen.io/bcaure/pen/RwapqZW?editors=1011

简而言之,我不知道如何修复你的代码,因为这是一个回调地狱。

// Mock API and data
const bucketArray = [[{item: 'item1'}], [{item: 'item2'}], [{item: 'item3'}]];
const getAxious = item => { 
return new Promise((resolve, reject) => resolve({data: 'API data'}));
}
// Return promise that combines API data + input item
const recToPromise = rec => rec.map(item => { 
return new Promise((resolve, reject) => getAxious(item)
.then(data => resolve({item, data}))); 
});
// Flatten array
const recPromisesFlatten = bucketArray.flatMap(recToPromise);
Promise.all(recPromisesFlatten)
.then(res => { 
const flattenRes = res.flatMap(({item, data}) => ({ Symbol: item, Open: data }));
console.log(JSON.Stringify(flattenRes))
});

我建议调试错误:

  1. 首先构建您的promise数组
  2. 然后运行Promise.all
  3. 然后组合您的数据

额外功能:您可以看到flatMap而不是reduce,以获得更好的可读性。

最新更新