Шта је то и како га користити

Када пишете ЈаваСцрипт апликације, можда сте наишли на асинхроне функције, као што је функција преузимања у претраживачу или функција реадФиле у Нодејс-у.

Можда сте добили неочекиване резултате ако сте користили било коју од ових функција као и обично. То је зато што су то асинхроне функције. Овај чланак говори шта то значи и како да користите асинхроне функције као професионалац.

Увод у синхроне функције

ЈаваСцрипт је језик са једним навојем који може да ради само једну по једну ствар. То значи да ако процесор наиђе на функцију која траје дуго, ЈаваСцрипт чека док се цела функција не изврши пре него што пређе на друге делове програма.

Већину функција у потпуности извршава процесор. То значи да ће током извршавања наведених функција, без обзира колико то траје, процесор бити потпуно заузет. Оне се називају синхроне функције. Пример синхроне функције је дефинисан у наставку:

function add(a, b) {
    for (let i = 0; i < 1000000; i ++) {
        // Do nothing
    }
    return a + b;
}

// Calling the function will take a long time
sum = add(10, 5);

// However, the processor cannot move to the 
console.log(sum);

Ова функција изводи велику петљу чије извршавање траје много времена пре него што врати збир своја два аргумента.

Након дефинисања функције, позвали смо је и сачували њен резултат у променљивој сум. Затим смо евидентирали вредност променљиве суме. Иако извршавање функције додавања траје неко време, процесор не може да пређе на евиденцију суме док се извршење не заврши.

Огромна већина функција на које ћете наићи ће се понашати на предвидљив начин попут оног изнад. Међутим, неке функције су асинхроне и не понашају се као обичне функције.

Увод у асинхроне функције

Асинхроне функције обављају већину свог посла ван процесора. То значи да иако функција може да потраје неко време да заврши извршење, процесор ће бити незаузет и слободан да ради више.

Ево примера такве функције:

fetch('https://jsonplaceholder.typicode.com/users/1');

Да би побољшао ефикасност, ЈаваСцрипт омогућава процесору да пређе на друге задатке који захтевају ЦПУ чак и пре него што је извршење асинхроне функције завршено.

Пошто је процесор кренуо даље пре него што је извршење асинхроне функције завршено, њен резултат неће бити одмах доступан. То ће бити на чекању. Ако би процесор покушао да изврши друге делове програма који зависе од резултата на чекању, добили бисмо грешке.

  Која је разлика, шта је најбоље?

Према томе, процесор треба да извршава само делове програма који не зависе од резултата на чекању. Да би то урадио, савремени ЈаваСцрипт користи обећања.

Шта је обећање у ЈаваСцрипт-у?

У ЈаваСцрипт-у, обећање је привремена вредност коју асинхрона функција враћа. Обећања су окосница модерног асинхроног програмирања у ЈаваСцрипт-у.

Након што је обећање створено, дешава се једна од две ствари. Или се решава када се успешно произведе повратна вредност асинхроне функције или се одбија у случају грешке. Ово су догађаји унутар животног циклуса обећања. Стога, можемо да приложимо руковаоце догађајима обећању које ће бити позвано када се реши или одбије.

Сав код који захтева коначну вредност асинхроне функције може да се прикачи руковаоцу догађаја обећања када се реши. Сав код који обрађује грешку одбијеног обећања такође ће бити везан за одговарајући руковалац догађаја.

Ево примера где читамо податке из датотеке у Нодејс-у.

const fs = require('fs/promises');

fileReadPromise = fs.readFile('./hello.txt', 'utf-8');

fileReadPromise.then((data) => console.log(data));

fileReadPromise.catch((error) => console.log(error));

У првом реду увозимо модул фс/промисес.

У другом реду позивамо функцију реадФиле, преносећи име и кодирање датотеке чији садржај желимо да прочитамо. Ова функција је асинхрона; дакле, враћа обећање. Обећање чувамо у променљивој филеРеадПромисе.

У трећем реду смо приложили слушалац догађаја када се обећање реши. Ово смо урадили тако што смо позвали тада метод на обећаном објекту. Као аргумент нашем позиву тадашњем методу, проследили смо функцију за покретање ако и када се обећање реши.

У четвртом реду смо приложили слушаоца за кога се обећање одбија. Ово се ради позивањем методе цатцх и прослеђивањем обрађивача догађаја грешке као аргумента.

Алтернативни приступ је коришћење кључних речи асинц и аваит. Следеће ћемо покрити овај приступ.

Асинц и Аваит објашњени

Кључне речи Асинц и Аваит се могу користити за писање асинхроног Јавасцрипт-а на начин који синтаксички изгледа боље. У овом одељку ћу објаснити како да користите кључне речи и какав ефекат оне имају на ваш код.

Кључна реч аваит се користи за паузирање извршавања функције док се чека да се асинхрона функција заврши. Ево примера:

const fs = require('fs/promises');

function readData() {
	const data = await fs.readFile('./hello.txt', 'utf-8');

    // This line will not be executed until the data becomes available
	console.log(data);
}

readData()

Користили смо кључну реч аваит док смо позивали реадФиле. Ово је наложило процесору да сачека док се датотека не прочита пре него што се следећи ред (цонсоле.лог) може извршити. Ово помаже да се осигура да код који зависи од резултата асинхроне функције неће бити извршен док резултат не постане доступан.

  Како користити Антхропиц-ову нову продавницу Цлауде 3 АИ Промпт-а

Ако сте покушали да покренете горњи код, наишли бисте на грешку. То је зато што се аваит може користити само унутар асинхроне функције. Да бисте функцију прогласили асинхроном, користите кључну реч асинц пре декларације функције на следећи начин:

const fs = require('fs/promises');

async function readData() {
	const data = await fs.readFile('./hello.txt', 'utf-8');

    // This line will not be executed until the data becomes available
	console.log(data);
}

// Calling the function so it runs
readData()

// Code at this point will run while waiting for the readData function to complete
console.log('Waiting for the data to complete')

Ако покренете овај исечак кода, видећете да ЈаваСцрипт извршава спољашњу цонсоле.лог док чека да подаци прочитани из текстуалне датотеке постану доступни. Када постане доступан, извршава се цонсоле.лог унутар реадДата.

Руковање грешкама при коришћењу кључних речи асинц и аваит се обично врши помоћу покушај да ухватиш блокова. Такође је важно знати како да петља са асинхроним кодом.

Асинц и аваит су доступни у модерном ЈаваСцрипт-у. Традиционално, асинхрони код је написан коришћењем повратних позива.

Увод у повратне позиве

Повратни позив је функција која ће бити позвана када резултат буде доступан. Сав код који захтева повратну вредност биће стављен у повратни позив. Све остало ван повратног позива не зависи од резултата и стога је слободно за извршење.

Ево примера који чита датотеку у Нодејс-у.

const fs = require("fs");

fs.readFile("./hello.txt", "utf-8", (err, data) => {

	// In this callback, we put all code that requires 
	if (err) console.log(err);
	else console.log(data);
});

// In this part here we can perform all the tasks that do not require the result
console.log("Hello from the program")

У првом реду увезли смо модул фс. Затим смо позвали функцију реадФиле модула фс. Функција реадФиле ће прочитати текст из датотеке коју наведемо. Први аргумент је која је то датотека, а други наводи формат датотеке.

Функција реадФиле асинхроно чита текст из датотека. Да би то урадио, узима функцију као аргумент. Овај аргумент функције је функција повратног позива и биће позван када се подаци прочитају.

Први аргумент који се прослеђује када се позове функција повратног позива је грешка која ће имати вредност ако се грешка појави док је функција покренута. Ако не дође до грешке, биће недефинисана.

Други аргумент који се прослеђује повратном позиву је податак прочитан из датотеке. Код унутар ове функције ће приступити подацима из датотеке. Код ван ове функције не захтева податке из датотеке; стога се може извршити док се чекају подаци из датотеке.

  Шта је ново Снапцхат ажурирање?

Покретање горњег кода би произвело следећи резултат:

Кључне ЈаваСцрипт функције

Постоје неке кључне карактеристике и карактеристике које утичу на то како асинхронизовани ЈаваСцрипт функционише. Они су добро објашњени у видеу испод:

У наставку сам укратко изложио две важне карактеристике.

#1. Сингле-тхреадед

За разлику од других језика који дозвољавају програмеру да користи више нити, ЈаваСцрипт вам дозвољава да користите само једну нит. Нит је низ инструкција које логично зависе једна од друге. Више нити омогућава програму да изврши другу нит када се наиђу на операције блокирања.

Међутим, више нити додаје сложеност и отежава разумевање програма који их користе. Због тога је већа вероватноћа да ће грешке бити уведене у код и било би тешко отклонити грешке у коду. ЈаваСцрипт је направљен једнонитним ради једноставности. Као језик са једним навојем, ослања се на то да је вођен догађајима како би ефикасно управљао операцијама блокирања.

#2. Догађај-дривен

ЈаваСцрипт је такође вођен догађајима. То значи да се неки догађаји дешавају током животног циклуса ЈаваСцрипт програма. Као програмер, можете приложити функције овим догађајима, и кад год се догађај деси, приложена функција ће бити позвана и извршена.

Неки догађаји могу бити резултат тога што је резултат операције блокирања доступан. У овом случају, придружена функција се затим позива са резултатом.

Ствари које треба узети у обзир када пишете асинхрони ЈаваСцрипт

У овом последњем одељку поменућу неке ствари које треба узети у обзир приликом писања асинхроног ЈаваСцрипт-а. Ово ће укључивати подршку за прегледач, најбоље праксе и важност.

Подршка претраживача

Ово је табела која приказује подршку обећања у различитим претраживачима.

Извор: цаниусе.цом

Ово је табела која приказује подршку асинхронизованих кључних речи у различитим претраживачима.

Извор: цаниусе.цом

Најбоље праксе

  • Увек се одлучите за асинц/аваит, јер вам помаже да напишете чистији код о коме је лако размишљати.
  • Руковати грешкама у блоковима три/цатцх.
  • Користите кључну реч асинц само када је потребно сачекати резултат функције.

Важност асинхроног кода

Асинхрони код вам омогућава да пишете ефикасније програме који користе само једну нит. Ово је важно јер се ЈаваСцрипт користи за прављење веб локација које врше много асинхроних операција, као што су мрежни захтеви и читање или писање датотека на диск. Ова ефикасност је омогућила временима извођења као што је НодеЈС да расте у популарности као преферираном времену извођења за сервере апликација.

Завршне речи

Ово је био дугачак чланак, али у њему смо могли да покријемо како се асинхроне функције разликују од обичних синхроних функција. Такође смо покрили како да користимо асинхрони код користећи само обећања, асинц/аваит кључне речи и повратне позиве.

Поред тога, покрили смо кључне карактеристике ЈаваСцрипт-а. У последњем одељку смо завршили покривањем подршке за прегледач и најбоље праксе.

Затим погледајте Ноде.јс-ова често постављана питања за интервјуе.