async function
should have await
expression JS-0116async
function without any await
expressions 36 * @param {string} input
37 * @returns void
38 */
39const makeStatsFromInput = async (input) => { 40 currentChatText = ""; 41 if(typeof(input) !== "string") return; 42 const iconNames = input.trimStart().split(" ").filter(t => t.startsWith("~")); 43 const icons = iconNames.map(t => iconMatch(t.slice(1))).filter(t => t !== false); 44 if(icons.length === 0) return; 45 46 Promise.all(icons.map(icon => { 47 return new Promise((resolve) => { 48 resolve({ 49 "key": icon.nameHash, 50 "value": streamerIconStats[icon.nameHash] + 1 || 1 51 }); 52 }) 53 })) 54 .then(async data => { 55 const merged = {}; 56 for(const info of data) merged[info.key] = info.value; 57 58 const newiconStats = { 59 ...streamerIconStats, 60 ...merged, 61 } 62 63 const updateData = { 64 ...browserLocalData, 65 } 66 updateData.iconStats[watchingStreamer] = newiconStats; 67 68 await chrome.storage.local.set(updateData); 69 browserLocalData = await chrome.storage.local.get(); 70 streamerIconStats = browserLocalData.iconStats[watchingStreamer]; 71 logger.debug(`update browser local data`, browserLocalData); 72 }) 73 .catch(err => { 74 console.trace(err); 75 logger.error(err); 76 }) 77} 78
79
80/**
async
function without any await
expressions599/**
600 * html 요소와 관련이 큰 함수를 선언한다.
601 */
602const run_1_functions = async () => {603 if(fail)604 {605 logger.info(`[find_3_streamer]`, error);606 return;607 }608609 try610 {611 logger.debug("[run_1_functions]");612 }613 catch(err)614 {615 fail = true;616 error = err;617 }618 finally619 {620 return;621 }622}623
624////////////////////////////////////////
async
function without any await
expressions 6 * 그리고 로컬 저장소에서 불러온 값을 이용해서
7 * streamerIcons, streamerIconStats 변수를 설정한다.
8 */
9const find_3_streamer = async () => {10 if(fail)11 {12 logger.info(`[find_2_elements]`, error);13 return;14 }1516 try 17 { 18 if(isPopout)19 {20 /**21 * https://www.twitch.tv/popout/streamer/chat22 */23 watchingStreamer = location.href.split("/").slice(-2)[0];24 }25 else if(isVod)26 {27 /**28 * https://www.twitch.tv/videos/video_id_numbers29 */30 watchingStreamer = profileArea.href.split("/").pop().split("?")[0];31 }32 else if(isClip)33 {34 /**35 * https://www.twitch.tv/streamer/clip/clip_id36 */37 watchingStreamer = location.href.split("twitch.tv/").pop().split("/")[0];38 }39 else if(isLive) // live40 {41 /**42 * https://www.twitch.tv/streamer?asdf43 */44 watchingStreamer = location.href.split("/").pop().split("?")[0];45 }4647 /**48 * TEST STREAMER49 */50 if(watchingStreamer === "drowsyprobius") watchingStreamer = "funzinnu";51 52 if(!streamers.includes(watchingStreamer))53 {54 fail = true;55 error = `${watchingStreamer} is not in our whitelist`;56 logger.info(error);57 return [fail, error];58 }59 if(!tagCommandEnabledStreamers.includes(watchingStreamer))60 {61 logger.info(`${watchingStreamer} does not support tag commands.`)62 }63 logger.debug(`[find_3_streamer] ${watchingStreamer}`);64 65 streamerIcons = iconMetadata[watchingStreamer].icons;66 streamerIconStats = iconStats[watchingStreamer];6768 logger.info(`[find_3_streamer] loaded total ${streamerIcons.length} icons and statistics`, streamerIconStats);6970 return [streamerIcons, streamerIconStats];71 }72 catch(err)73 {74 fail = true;75 error = err;76 }77 finally78 {79 return;80 }81}82
83////////////////////////////////////////
async
function without any await
expressions64 * 실행 중에 변경될 수 있는
65 * 전역 변수 선언
66 */
67const init_2_variables = async () => {68 logger.debug("[init_2_variables]");69 return;70}71
72////////////////////////////////////////
async
function without any await
expressions118 headers: {"Content-Type": "application/json"}
119 }
120 )
121 .then(async res => {122 return apiParser(res);123 })124 .catch(async e => {
125 throw e;
126 })
A function that does not contain any await
expressions should not be async
(except for some edge cases
in TypeScript which are discussed below).
Asynchronous functions in JavaScript behave differently than other functions in two important ways:
Promise
.await
operator inside them.Functions are made async
so that we can use the await
operator inside them.
Consider this example:
async function fetchData(processDataItem) {
const response = await fetch(DATA_URL);
const data = await response.json();
return data.map(processDataItem);
}
Asynchronous functions that don't use await
might be an unintentional result of refactoring.
Note: This issue ignores async generator functions.
Generators yield
rather than return
a value and async
generators might yield all the values of another async generator without ever actually needing to use await
.
In TypeScript, one might feel the need to make a function async
to comply with type signatures defined by an interface.
Ideally, the code should be refactored to get rid of such restrictions, but sometimes that isn't feasible
(For example, when we are implementing an interface defined in a 3rd party library like Next.js).
This situation can easily be circumvented by returning the value with a call to Promise.resolve
:
interface HasAsyncFunc {
getNum: () => Promise<number>
}
// Not recommended:
const o: HasAsyncFunc = {
async getNum() { return 1 }
}
// Recommended:
const o: HasAsyncFunc = {
// We only use `Promise.resolve` to adhere to the type
// of the surrounding object.
getNum() { return Promise.resolve(1) }
}
It is also advised to add a comment near the redundant promise to make the intent clear.
async function fetchData(): string {
// `readFileSync` is a synchronous function that blocks
// the main thread, and thus does not need to be `await`ed
return fs.readFileSync("data.txt", "utf-8");
}
performAction(async () => { console.log("no awaits in here") });
async function fetchDataAsync(): Promise<string> {
return await fs.readFile("data.txt", "utf-8")
}
performAction(async () => { await writeToFile(data) });
// Allow empty functions.
async function no_op() {}