Here is My useEffect is going in Infinite loop, becouse checkimage value is changing becouse the value is assigned in fetch(), so anyone know how to solve it. I want to get varient data with image but I can't get it in first time.
help me if you can
Thank You
useEffect(() => {
fetch({ pagination });
}, [checkimage]);
const fetch = async (params = {}) => {
if (type == 'product') {
dispatch(await ProductService.getProduct(productId))
.then((res) => {
let variantsdatas = getImageArns(res.data.variants);
getImages(variantsdatas);
let record = [];
record.push(res.data)
setVarientsData(record)
})
.catch((err) => {});
} else {
dispatch(await ProductService.getProducts())
.then((res) => {
console.info({ 'res.data': res.data });
setVarientsData(res.data.products);
setPagination({
...params.pagination,
total: res.total_count,
});
})
.catch((err) => {});
}
};
const getImageArns = (variantsdatas) => {
const variantImageArns = [];
variantsdatas.forEach((variant, index) => {
variant[index] = variant.variantId;
if (variant.variantImagesListResponseDto.images.length > 0) {
let variantImageObj = {
variantId: variant.variantId,
arnUrl: variant.variantImagesListResponseDto.images[0].docUrl,
};
variantImageArns.push(variantImageObj);
}
});
// console.info('id', variantImageArns);
return variantImageArns;
};
const getImages = async (variantsdatas) => {
const images = [];
dispatch(await ProductVariantService.getImage(variantsdatas))
.then((res) => {
console.info(res.data.fileResponseDtoList);
let presignedURLs = {};
res.data.fileResponseDtoList.map(
(i) => (
(presignedURLs = {
variantId: i.variantId,
arnUrl: i.presignedURL,
}),
console.info(presignedURLs),
images.push(presignedURLs)
)
);
setcheckimage(images);
})
.catch((err) => {
console.info('Get Error District...');
});
};
var img = 'img';
const setVarientsData = (products) => {
let varients_array = [];
if (products.length > 0) {
products.forEach((product) => {
if (product.variants.length > 0) {
let product_varients = product.variants;
product_varients.forEach((varient) => {
for (var f = 0; f < checkimage.length; f++) {
if(checkimage[f].variantId == varient.variantId){
img = checkimage[f].arnUrl;
f = checkimage.length
}
else{
img = 'img2';
}
}
varients_array.push({
image: img,
variantId: varient.variantId,
productVariantName: varient.variantName,
productName: product.productName,
brand: '-',
sellerSku: varient.productVariantCode,
status: product.status,
category: product.subCategoryInfo.categoryInfo.categoryName,
subCategoryName: product.subCategoryInfo.subCategoryName,
state: '-',
market: '-',
mrp: varient.price.amount + ' ' + varient.price.currency,
sellingPrice: '-',
manufacturer_product_variant_code:
varient.manufacturerProductVariantCode,
product_varient_code: varient.azProductVariantLongCode,
hsnCode: varient.hsnCode,
});
});
}
});
}
setVarients(varients_array);
console.info('varients_array ====>>', {varients_array})
};
I think that if I stop to run blow code getImage function then I can get my result
am I right?
But I tried It too but is also not happening properly.
a quick and dirty fix could be to work with a counter.
and only run the fetch in the useEffect, when counter is 0.
have you tried that?
Related
Tried fixing it multiple times and looked over it multiple times but keep on getting the same error: "react-dom.development.js:86 Warning: Received NaN for the children attribute. If this is expected, cast the value to a string."
Need help reviewing this code below and see why that error keeps on showing up
import React, {useState, useEffect} from "react";
function BlackjackGame() {
// useState will return a tuple where the first parameter ()
// ...is the current state of the deck. () allows us to update
// ...the state of the deck.
const [deckFilled, setDeckFilled] = useState(false);
// declaring a new state variable for the card deck
const [cardDeck, setCardDeck] = useState({});
// PLAYER :
// declaring a new state variable for the player
const [gamePlayer, setPlayer] = useState([]);
// declaring a new state variable that holds the player points
const [playerPoints, setPlayerPoints] = useState(0);
// new state variable for optional player points
const [optlPPt, setOptlPPt] = useState(0);
const [showOptlPPt, setShowOptlPPt] = useState(false);
// new state variable for the player cards
const [enablePlayerCards, setEnablePlayerCards] = useState(true);
// new state variable for the when the player is done with their round
const [endOfPlayerRound, setEndOfPlayerRound] = useState(false);
// new state variable for the player buy-in
let playerCurrentBuyIn = 5000;
const [playerBalance, setPlayerBalance] = useState(playerCurrentBuyIn);
// GAME :
// setting the variable for the bet
const[currBet, setBet] = useState(0);
// game round
let round = 3;
const [gameRound, setGameRound] = useState(round);
// game bet
const [placeGameBet, setPlaceGameBet] = useState(true);
// game message
const [msg, setMsg] = useState('How much are you betting?')
const [betButton, setBetButton] = useState(true);
const[forDouble, setForDouble] = useState(false);
const[savedGames, setSavedGames] = useState(false);
const[endOfGame, setEndOfGame] = useState(false);
const[results, setResults] = useState([]);
// DEALER :
// declaring a new state variable for the dealer
const [dealer, setDealer] = useState([]);
// declaring the state variable for that holds the dealer points
const [dealerPoints, setDealerPoints] = useState(0);
// new state variable for optional dealer points
const [optlDlrPt, setOptlDlrPt] = useState(0);
const [showOptlDlrPt, setShowOptlDlrPt] = useState(false);
// back of the dealers card
const [backOfDealersCard, setBackofDealersCard] = useState(false);
// variable for the Hit Button
let hitButton = enablePlayerCards === true && endOfPlayerRound === false && placeGameBet === false;
// variable for the stand button
let standButton = endOfPlayerRound === false && enablePlayerCards === true && placeGameBet === false;
// variable for the double button
let doubleButton = gamePlayer.length === 2 && endOfPlayerRound === false &&
placeGameBet === false && playerBalance >= currBet;
// passing an empty dependencies array to the useEffect hook...
// ...so it runs only when the component mounts
useEffect(() => {
// creating a new deck side effect
composeNewDeck();
window.addEventListener('beforeunload', (event) => {
save()
// cancel the event by the standard
event.preventDefault();
// return the value
return event.returnValue = 'Did you make up your mind?';
})
return() => {
window.removeEventListener('beforeunload', (event) => {
save()
// cancel the event by the standard
event.preventDefault();
// return the value
return event.returnValue = 'Did you make up your mind?';
})
}
}, )
useEffect(() => {
setPlayerPoints(() => {return 0})
setOptlPPt(() => {return 0})
gamePlayer.map((card) => (
card.value === 'Jack' || card.value === 'King' || card.value === 'Queen' ? (
setPlayerPoints((points) => { return points + 10}),
setOptlPPt((points) => { return points + 10})
):
card.value === 'Ace' ? (
setPlayerPoints((points) => { return points + 11}),
setOptlPPt((points) => { return points + 1}),
setShowOptlPPt(() => {return true})
):(
setPlayerPoints((points) => { return points + parseInt(card.value) }),
setOptlPPt((points) => { return points + parseInt(card.value)})
)
))
}, [gamePlayer])
useEffect(() => {
setDealerPoints(() => {return 0})
setOptlDlrPt(() => {return 0})
if (dealer.length === 2 && endOfPlayerRound === false) {
if (dealer[0].value === 'Jack' ||
dealer[0].value === 'King' ||
dealer[0].value === 'Queen' ) {
setDealerPoints((points) => { return points + 10})
setOptlDlrPt((points) => { return points + 10})
} else if (dealer[0].value === 'Ace') {
setDealerPoints((points) => { return points + 11})
setOptlDlrPt((points) => { return points + 1})
setShowOptlDlrPt(() => { return true})
} else {
setDealerPoints((points) => { return points + parseInt(dealer[0].value) })
setOptlDlrPt((points) => { return points + parseInt(dealer[0].value)})
}
} else {
dealer.map((card) => (
card.value === 'Jack' ||
card.value === 'King' ||
card.value === 'Queen' ? (
setDealerPoints((points) => { return points + 10}),
setOptlDlrPt((points) => { return points + 10})
):
card.value === 'Ace' ? (
setDealerPoints((points) => { return points + 11}),
setOptlDlrPt((points) => { return points + 1}),
setShowOptlDlrPt(() => {return true})
): (
setDealerPoints((points) => { return points + parseInt(card.value) }),
setOptlDlrPt((points) => { return points + parseInt(card.value)})
)
))
}
}, [dealer, endOfPlayerRound])
useEffect(() => {
if (playerPoints > 21 && optlPPt > 21) {
setEnablePlayerCards(() => {return false})
setMsg('Uh Oh...Looks like you lost');
setTimeout(() => {
dealerWon();
}, 2000);
} else if (playerPoints === 21 || optlPPt === 21) {
setMsg("Now you see...Blackjack!")
setEnablePlayerCards(() => {return false})
setTimeout(() => {
stand()
}, 2000);
} else {
forDouble === true && stand();
}
}, [playerPoints])
useEffect(() => {
if ( ((endOfPlayerRound === true && dealerPoints <= 16) ||
(dealerPoints > 21 && optlDlrPt <= 16)) && dealerPoints !== 0) {
setMsg("Computers turn");
draw(false, drawFirstCard);
} else if (endOfPlayerRound === true && dealerPoints !== 0) {
let comparePlayersPoint;
let compareDealerPoint;
if (playerPoints > 21 && (optlPPt > 0 && optlPPt <= 21) ) {
comparePlayersPoint = optlPPt;
} else {
comparePlayersPoint = playerPoints;
}
if( dealerPoints > 21 && optlDlrPt > 21){
compareDealerPoint = 0;
} else if (dealerPoints > 21 && (optlDlrPt > 0 && optlDlrPt <= 21)) {
compareDealerPoint = optlDlrPt;
} else if (dealerPoints <= 21) {
compareDealerPoint = dealerPoints;
}
if( (21 - comparePlayersPoint) < (21 - compareDealerPoint) ) {
setMsg("You won")
setTimeout(() => {
playerWon();
}, 2000);
} else if ((21 - comparePlayersPoint) > (21 - compareDealerPoint)){
setMsg("Computer won")
setTimeout(() => {
dealerWon();
}, 2000);
} else {
setMsg("Draw")
setTimeout(() => {
noWinner();
}, 2000);
}
}
}, [dealerPoints])
useEffect(() => {
if (placeGameBet === true) {
setMsg("How much are you betting?");
setBetButton(true);
}
}, [placeGameBet])
useEffect(() => {
if ( gameRound > 5 ) {
endGame();
} else if (gameRound !== 1 && savedGames === false) {
nextRound();
} else {
setSavedGames(false);
}
}, [gameRound])
// calling the Deck Of Cards API to fecth the cards
const composeNewDeck = () => {
fetch(deckOfCardsLink + shuffleDeckOfCards + deckAmt, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
})
.then(response => response.json())
.then(responseData => {
setDeckFilled(() => { return true; })
setCardDeck( () => { return {...responseData}; })
})
.catch(err => {
console.log('error : ' + err);
});
}
// calling the Deck Of Cards API to draw a card
const draw = (forPlayers, amtOfCards) => {
fetch(deckOfCardsLink + cardDeck.deck_id + amtOfCards, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
})
.then(response => response.json())
.then(responseData => {
if (forPlayers === true) {
setPlayer((playerHand) => { return [...playerHand, ...responseData.cards]; })
} else {
setDealer((dealerHand) => { return [...dealerHand, ...responseData.cards]; })
}
})
.catch(err => {
console.log('error : ' + err);
});
}
// calling the Deck Of Cards API to shuffle the card deck
const shuffleDeck = (deckId) => {
fetch(deckOfCardsLink + deckId + reShuffleDeckOfCard, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
})
.then(response => response.json())
.then(responseData => {
setDeckFilled(() => { return true; })
setCardDeck( () => { return {...responseData}; })
})
.catch(err => {
console.log('error : ' + err);
});
}
const stand = () => {
setBackofDealersCard(() => {return true})
setTimeout(() => {
setEndOfPlayerRound(() => {return true})
setEnablePlayerCards(() => {return false})
}, 250);
}
const double = () => {
setForDouble(true);
setMsg("Going for double!")
setPlayerBalance((balance) => {return balance - currBet})
setBet((bet) => {return bet+bet})
draw(true, drawFirstCard);
}
const startRound = () => {
setEndOfPlayerRound(false);
setEnablePlayerCards(true);
setPlaceGameBet(false);
setBetButton(false);
setMsg("Your turn");
if (deckFilled === true) {
draw(true, drawSecondCard);
draw(false, drawSecondCard);
}
}
const bet = (amount) => {
if (playerBalance - amount >= 0) {
setPlayerBalance((balance) => { return balance - amount});
setBet((bet) => {return bet + amount})
}
}
const playerWon = () => {
setPlayerBalance((balance) => {return balance + (currBet * 1.5)})
setGameRound((round) => {return round + 1});
}
const dealerWon = () => {
setGameRound((round) => {return round + 1});
}
const noWinner = () => {
setPlayerBalance((balance) => {return balance + currBet})
setGameRound((round) => {return round + 1});
}
const nextRound = () => {
setBackofDealersCard(false);
setForDouble(false);
setShowOptlDlrPt(false);
setShowOptlPPt(false);
setPlayerPoints(0);
setOptlPPt(0);
setDealerPoints(0);
setOptlDlrPt(0);
setPlaceGameBet(true);
setBetButton(true);
setBet(0);
setPlayer([]);
setDealer([]);
}
const endGame = () => {
setEndOfGame(true);
setBet(0);
setMsg("Game Over");
let rank = JSON.parse(localStorage.getItem("rank"));
if( rank === undefined || rank === null) {
localStorage.setItem("rank", JSON.stringify({
points: [playerBalance]
}))
} else {
let sortedRank = rank.points.sort(function(a, b) {
return b - a;
})
if (sortedRank.length<=2) {
setResults([...sortedRank])
} else {
setResults([sortedRank[0],sortedRank[1],sortedRank[2]])
}
localStorage.setItem("rank", JSON.stringify({
points: [...rank.points, playerBalance]
}))
}
}
const reset = () => {
setEndOfGame(false);
setDeckFilled(false);
shuffleDeck(cardDeck.deck_id);
nextRound();
setGameRound(3);
setPlayerBalance(5000);
}
const save = () => {
localStorage.setItem("savedGame", JSON.stringify(
{
deckFilled: deckFilled,
cardDeck: cardDeck,
gamePlayer: gamePlayer,
dealer: dealer,
playerPoints: playerPoints,
dealerPoints: dealerPoints,
optlPPt: optlPPt,
showOptlPPt: showOptlPPt,
optlDlrPt: optlDlrPt,
showOptlDlrPt: showOptlDlrPt,
enablePlayerCards: enablePlayerCards,
endOfPlayerRound: endOfPlayerRound,
playerBalance: playerBalance,
currBet: currBet,
backOfDealersCard: backOfDealersCard,
gameRound: gameRound,
placeGameBet: placeGameBet,
msg: msg,
betButton: betButton,
forDouble: forDouble,
}
));
}
const load = () => {
setSavedGames(true);
let gameSave = JSON.parse(localStorage.getItem('savedGame'));
if (gameSave !== undefined) {
setCardDeck(gameSave.cardDeck);
setPlayer(gameSave.gamePlayer);
setDealer(gameSave.dealer);
setPlayerPoints(gameSave.playerPoints);
setDealerPoints(gameSave.dealerPoints);
setOptlPPt(gameSave.optlPPt);
setShowOptlPPt(gameSave.showOptlPPt);
setOptlDlrPt(gameSave.optlDlrPt);
setShowOptlDlrPt(gameSave.showOptlDlrPt);
setEnablePlayerCards(gameSave.enablePlayerCards);
setEndOfPlayerRound(gameSave.endOfPlayerRound);
setPlayerBalance(gameSave.playerBalance);
setBet(gameSave.currBet);
setBackofDealersCard(gameSave.backOfDealersCard);
setGameRound(gameSave.gameRound);
setPlaceGameBet(gameSave.placeGameBet);
setMsg(gameSave.msg);
setBetButton(gameSave.betButton);
setForDouble(gameSave.forDouble);
setDeckFilled(gameSave.deckFilled);
}
}
This question already has answers here:
JavaScript array .reduce with async/await
(11 answers)
Closed 6 months ago.
I need to fetch values from another API using the guid inside this particular array, then group them together (hence I used reduce Javascript in this case)
However, I could not get those values sumEstimatedHours and sumWorkedHours as expected. Can someone suggest a method please?
export const groupProjectsByPM = (listOfProjects) => {
const dir = "./json";
const estimatedHours = fs.existsSync(dir)
? JSON.parse(fs.readFileSync("./json/phases.json", "utf-8"))
: null;
let sumWorkedHours, sumEstimatedHours;
const groupedProjects = listOfProjects?.reduce(
(
group,
{
guid,
projectOwner: { name: POName },
name,
customer: { name: customerName },
deadline,
calculatedCompletionPercentage,
}
) => {
listOfProjects.map(async (element, index) => {
// const element = listOfProjects[index];
sumWorkedHours = await getWorkhoursByProject(element?.guid).then(
(res) => {
return res.reduce((acc, cur) => {
return acc + cur.quantity;
}, 0);
}
);
const filteredEstimatedHours = estimatedHours.filter(
(item) => item.project.guid === element.guid
);
sumEstimatedHours = filteredEstimatedHours.reduce((acc, cur) => {
return acc + cur.workHoursEstimate;
}, 0);
group[POName] = group[POName] || [];
group[POName].push({
guid,
name,
POName,
customerName,
deadline,
calculatedCompletionPercentage,
sumEstimatedHours,
sumWorkedHours,
});
return group;
});
return group;
},
[]
);
return groupedProjects;
};
here is an example of async/await inside reduce:
let's assume that we have an array of numbers
const arrayOfNumbers = [2,4,5,7,6,1];
We are going to sum them using reduce function:
const sumReducer = async () => {
const sum = await arrayOfNumbers.reduce(async (promisedSum, num) => {
const sumAcc = await promisedSum
// any promised function can be called here..
return sumAcc + num
}, 0)
console.log(sum)
}
So the trick is to remember to await the accumulator inside the reduce function
export const groupProjectsByPM = async (listOfProjects) => {
const dir = "./json";
const estimatedHours = fs.existsSync(dir)
? JSON.parse(fs.readFileSync("./json/phases.json", "utf-8"))
: null;
let sumWorkedHours, sumEstimatedHours;
const groupedProjects = await listOfProjects?.reduce(
async (
promisedGroup,
{
guid,
projectOwner: { name: POName },
name,
customer: { name: customerName },
deadline,
calculatedCompletionPercentage,
}
) => {
listOfProjects.map(async (element, index) => {
//accumulator in your case is group
const group = await promisedGroup;
// const element = listOfProjects[index];
sumWorkedHours = await getWorkhoursByProject(element?.guid).then(
(res) => {
return res.reduce((acc, cur) => {
return acc + cur.quantity;
}, 0);
}
);
const filteredEstimatedHours = estimatedHours.filter(
(item) => item.project.guid === element.guid
);
sumEstimatedHours = filteredEstimatedHours.reduce((acc, cur) => {
return acc + cur.workHoursEstimate;
}, 0);
group[POName] = group[POName] || [];
group[POName].push({
guid,
name,
POName,
customerName,
deadline,
calculatedCompletionPercentage,
sumEstimatedHours,
sumWorkedHours,
});
return group;
});
return group;
},
[]
);
return groupedProjects;
};
Best of luck ...
I am using React. On click of a button, the following function is executed:
const completeTaskHandler = (idValue) => {
setData((prevData) => {
const updatedData = [...prevData];
const updatedItem = updatedData.filter((ele) => ele.id === idValue)[0];
updatedItem.completed = true;
const newData = updatedData.filter((ele) => ele !== updatedItem);
newData.unshift(updatedItem);
return newData;
});
};
My data is an array of objects like this:
[{userId: 1, id: 2, title: "task 1", completed: true}, .....].
Basically I want to move the updated item to the start of the array. Is there any better solution for this?
updatedItem should not be mutated. And this string const newData = updatedData.filter((ele) => ele !== updatedItem); is not fine. You can do it like this :
const completeTaskHandler = (idValue) => {
setData((prevData) => {
const targetItem = prevData.find((ele) => ele.id === idValue);
const updatedItem = { ...targetItem, completed: true };
const filteredData = prevData.filter((ele) => ele.id !== idValue);
return [updatedItem, ...filteredData];
});
};
Even better to reducing an extra filter:
const completeTaskHandler = (idValue) => {
setData((prevData) => {
const targetIndex = prevData.findIndex((ele) => ele.id === idValue);
return [{ ...prevData[targetIndex], completed: true }].concat(prevData.slice(0, targetIndex + 1)) .concat(
prevData.slice(targetIndex + 1)
)
});
};
First find index of updated element using Array.findIndex(), then remove the same element using Array.splice() and add it to front of the array.
const completeTaskHandler = (idValue) => {
setData((prevData) => {
const updatedData = [...prevData];
const index = updatedData.findIndex(obj => obj.id === idValue);
const [updatedItem] = updatedData.splice(index, 1);
updatedItem.completed = true;
updatedData.unshift(updatedItem);
return updatedData;
});
};
The simplest one with only one forEach.
const completeTaskHandler = idValue => {
setData(prevData => {
let updatedItem = {}, newData = [];
prevData.forEach((ele) => {
if (ele.id === idValue) {
updatedItem = ele;
updatedItem.completed = true;
} else {
newData.push(ele);
}
});
newData.unshift(updatedItem);
return newData;
});
};
this is the first function , i have this function getAffliateCodesAsync() my requirement is to call this method from inside other function (function -2 >> generateCriBodyWithCreParameter(..))
and pass the returning value of >>(function-1) getAffliateCodesAsync(), into the third function and use that value in (function -3) checkLessorMagnitudeCode(..) and use the returning value of function-2 in function-3 at place where codeList is used, Please help
//function-1.
async function getAffliateCodesAsync(){
console.debug("==AFFILIATE_CODES==");
const ApplicationParameter = loopback.getModel('ApplicationParameter');
const applicationParamFieldValue = await ApplicationParameter.find({
where: {
fieldName: 'AFFILIATE_CODES'
},
fields: ['fieldValue']
});
return (applicationParamFieldValue.length)? applicationParamFieldValue.map(entity => String(entity['fieldValue'])):[];
}
//2.function-2
const generateCriBodyWithCreParameter = (positions, lotNumber, cutOffDate) => {
const CreParameter = loopback.getModel('CreParameter');
let creId = 1;
const positionData = [];
const content = [];
return CreParameter.find()
.then((creParameterList) => {
const promises = positions.map((position) => {
const cutOffDatePreviousMonth = getCutOffDatePreviousMonth(position.accountingDate);
return positionNativeProvider.getPositionInformationForPreviousCutOffDateForCriApf(
position, cutOffDatePreviousMonth)
.then((positionRetrieved) => {
const positionLowerCase = _.mapKeys(position, (value, key) => _.toLower(key));
const creParameters = _.filter(creParameterList, {
flowType: 'MI',
event: 'POSITION',
liabilityAmortizationMethod: position.liabilityAmortizationMethod
});
for (const creParameter of creParameters) {
const atollAmountValue = getAtollAmountValue(positionLowerCase, creParameter);
if (atollAmountValue && matchSigns(atollAmountValue, creParameter.amountSign)) {
const lineGenerated = checkContractLegalStatusForCri(position, creParameter,
atollAmountValue, content, creId, lotNumber, cutOffDate, positionRetrieved);
//No Line is generated in this case so the creId must not incremente
if (lineGenerated !== -1) {
positionData.push({
positionId: position.id,
creId
});
creId++;
}
}
}
});
});
return Promise.all(promises)
.then(() => {
return {
contentCreBody: content.join('\n'),
positionData
};
});
});
};
//function -3
const checkLessorMagnitudeCode = (lessorMagnitudeCode,codeList=[]) => {
if (!lessorMagnitudeCode) return false;
if (_.size(lessorMagnitudeCode) === 5 &&
(_.startsWith(lessorMagnitudeCode, 'S') || _.startsWith(lessorMagnitudeCode, 'T'))
&& codeList.includes(lessorMagnitudeCode)) {
return true;
}
return false;
};
//above codelist where I want to use the returning value
I have a problem with understanding how do async functions in js work. So I need to call async function for 5 times and measure the duration of every execution. In the end I should have an array with 5 time values.
I have smth like this
for (let i = 0; i < 5; i++) {
const run = async () => {
await test(thisTest, filename, unitTestDict);
};
measure(run).then(report => {
// inspect
const {tSyncOnly, tSyncAsync} = report;
// array.push(tSyncAsync)
console.log(`∑ = ${tSyncAsync}ms \t`);
}).catch(e => {
console.error(e)
});
}
Here I found the realization of time measure function:
class Stack {
constructor() {
this._array = []
}
push(x) {
return this._array.push(x)
}
peek() {
return this._array[this._array.length - 1]
}
pop() {
return this._array.pop()
}
get is_not_empty() {
return this._array.length > 0
}
}
class Timer {
constructor() {
this._records = new Map
/* of {start:number, end:number} */
}
starts(scope) {
const detail =
this._records.set(scope, {
start: this.timestamp(),
end: -1,
})
}
ends(scope) {
this._records.get(scope).end = this.timestamp()
}
timestamp() {
return performance.now()
}
timediff(t0, t1) {
return Math.abs(t0 - t1)
}
report(scopes, detail) {
let tSyncOnly = 0;
let tSyncAsync = 0;
for (const [scope, {start, end}] of this._records)
if (scopes.has(scope))
if (~end) {
tSyncOnly += end - start;
tSyncAsync += end - start;
const {type, offset} = detail.get(scope);
if (type === "Timeout")
tSyncAsync += offset;
}
return {tSyncOnly, tSyncAsync}
}
}
async function measure(asyncFn) {
const stack = new Stack;
const scopes = new Set;
const timer = new Timer;
const detail = new Map;
const hook = createHook({
init(scope, type, parent, resource) {
if (type === 'TIMERWRAP') return;
scopes.add(scope);
detail.set(scope, {
type: type,
offset: type === 'Timeout' ? resource._idleTimeout : 0
})
},
before(scope) {
if (stack.is_not_empty) timer.ends(stack.peek());
stack.push(scope);
timer.starts(scope)
},
after() {
timer.ends(stack.pop())
}
});
return await new Promise(r => {
hook.enable();
setTimeout(() => {
asyncFn()
.then(() => hook.disable())
.then(() => r(timer.report(scopes, detail)))
.catch(console.error)
}, 1)
})
}
I can call it inside the loop and get console.log with time for every iteration:
measure(run).then(report => {
// inspect
const {tSyncOnly, tSyncAsync} = report;
// array.push(tSyncAsync)
console.log(`∑ = ${tSyncAsync}ms \t`);
}).catch(e => {
console.error(e)
});
But when I try to push this console values to array, nothing comes out, the array remains empty. Is there a way to fill it in?