Properly setting a minimum delay when fetching data from external api

hi all. i'm trying to use the scryfall api, and they've got a requirement to allow at least 50-100ms of delay between each request to their api. how would i go about properly implementing that? i tried throwing the "whole" thing in a setTimeout() but that doesn't work as i'd expect, as it doesn't actually wait out the timeout and just returns undefined instantly.
import { z } from "zod";

import { createTRPCRouter, publicProcedure } from "~/server/api/trpc";

export const scryfallRouter = createTRPCRouter({
get: publicProcedure
.input(z.object({ name: z.string() }))
.query(async ({ input }) => {
setTimeout(async () => {
console.log("required delay");

const res = await fetch(
`https://api.scryfall.com/cards/named?fuzzy=${input.name}`,
);

if (!res.ok) {
throw new Error("Failed to fetch card");
}

const data = (await res.json()) as unknown;

console.log(data);
return data;
}, 150);
}),
});
import { z } from "zod";

import { createTRPCRouter, publicProcedure } from "~/server/api/trpc";

export const scryfallRouter = createTRPCRouter({
get: publicProcedure
.input(z.object({ name: z.string() }))
.query(async ({ input }) => {
setTimeout(async () => {
console.log("required delay");

const res = await fetch(
`https://api.scryfall.com/cards/named?fuzzy=${input.name}`,
);

if (!res.ok) {
throw new Error("Failed to fetch card");
}

const data = (await res.json()) as unknown;

console.log(data);
return data;
}, 150);
}),
});
i realize the placeholder post router, has something similar but i'm worried it won't actually delay the fetch call like required. any insights/comments are greatly appreciated :JinxHeart:
Solution:
await new Promise((resolve) => setTimeout(resolve, 150));
await new Promise((resolve) => setTimeout(resolve, 150));
Adding this, will delay whatever is happening by 150ms....
Jump to solution
2 Replies
Solution
Bumble
Bumble3mo ago
await new Promise((resolve) => setTimeout(resolve, 150));
await new Promise((resolve) => setTimeout(resolve, 150));
Adding this, will delay whatever is happening by 150ms. May I ask why do you want to fetch data more than 10 times a second?
tsuki
tsuki3mo ago
the point is that i don't want to fetch data more than 10 times a second. i've got a search field, that when changed, calls
fetch(`https://api.scryfall.com/cards/search?q=${input.cardName}`);
fetch(`https://api.scryfall.com/cards/search?q=${input.cardName}`);
the search input has some debouncing to ensure my internal trpc methods don't get called more than necessary, but i'd like to be completely sure, that the scryfall api, does not get hit more than is allowed, (ie. ~10 times each second). i'll mark your response as the solution, as it (so far at least) seems to be the proper way to "?rate limit?" the calls to the scryfall api, myself.