Ավելի լավ հոսքերի API հնարավոր է JavaScript-ի համար
Մեկնաբանություններ
Mewayz Team
Editorial Team
JavaScript-ի Streams API-ն խնդիր ունի, և մշակողները վերջապես խոսում են դրա մասին
Եթե երբևէ փորձել եք օգտագործել Streams API-ը JavaScript-ում դասագրքի օրինակից դուրս որևէ այլ բանի համար, ապա զգացել եք, որ բախումը տեղի է ունենում: Այն, ինչ պետք է լինի էլեգանտ, բաղադրելի աբստրակցիա՝ հաջորդական տվյալների մշակման համար՝ ֆայլեր կարդալը, HTTP պատասխանները մշակելը, տվյալների հավաքածուները իրական ժամանակում փոխակերպելը, հաճախ վերածվում է լայնաշերտ կաթսայի, հակադարձ ճնշման իմաստաբանության և API մակերեսի, որն ավելի շատ նման է ձեռնարկատիրական Java-ին, քան ժամանակակից JavaScript-ին: Ավելի լավ հոսքային պրիմիտիվ ստեղծելու շուրջ խոսակցությունը տարիներ շարունակ շարունակվում է TC39 առաջարկների, շրջանակային քննարկումների և բաց կոդով նախագծերի մեջ: 2026 թվականին այն հասնում է գագաթնակետին. Հարցն այն չէ, թե արդյոք հնարավոր է ավելի լավ հոսքային API, այլ այն է, թե իրականում ինչ տեսք ունի «ավելի լավը», և ինչն է մեզ հետ պահում:
Այնտեղ, որտեղ ընթացիկ հոսքերի API-ն պակասում է
WHATWG Streams ստանդարտը, որն ապահովում է ReadableStream, WritableStream և TransformStream բրաուզերների և գործարկման ժամանակներում, ինչպիսիք են Node.js-ը և Deno-ն, իսկական ինժեներական ձեռքբերում էր: Այն բերեց հակաճնշում, չեղարկում և համաժամանակյա կրկնություն վեբ-հայրենի տվյալների մշակման համար: Բայց գործնականում API-ն ծրագրավորողից շատ է պահանջում ընդհանուր գործառնությունների համար: Պարզ փոխակերպման հոսք ստեղծելու համար պահանջվում է TransformStream-ի ակնթարթավորումը transform մեթոդով, կառավարել կարգավորիչները և զգուշորեն կարգավորել միաձուլված իմաստաբանությունը, ինչը կազմում է map() կտորների վրա:
Համեմատեք սա այն բանի հետ, թե ինչպես են մշակողները աշխատում զանգվածների հետ: Array.prototype.map(), filter() և reduce() կոմպոզիտորական են, ընթեռնելի և պահանջում են գրեթե զրոյական արարողություն: Streams API-ն առաջարկում է այս էրգոնոմիկ կոմպոզիցիայից ոչ մեկը: Խողովակաշարը միանում է .pipeThrough()-ի միջոցով, սակայն փոխակերպման փուլերը կառուցելն այն է, որտեղ մշակողները կորցնում են ժամերն ու համբերությունը: Խողովակներով շղթաներով սխալների հետ վարվելը ևս մեկ ցավալի կետ է. սխալները չեն տարածվում ինտուիտիվ կերպով, և կոտրված խողովակաշարի վրիպազերծումը հաճախ նշանակում է մուտքագրման ժամանակավոր փոխակերպումներ պարզապես պարզելու համար, թե որտեղ են տվյալները թափվում կամ փչանում:
Սենյակում կա նաև Node.js փիղ: Node-ն ունի իր ժառանգական հոսքի իրականացումը (stream.Readable, stream.Writable), որը նախորդում է WHATWG ստանդարտին մոտ մեկ տասնամյակ: Երկու համակարգերը փոխգործունակ են միայն ադապտերների միջոցով, և շատ npm փաթեթներ դեռ օգտագործում են ավելի հին API: Մշակողները, որոնք աշխատում են տարբեր միջավայրերում (սերվերի կողմից մատուցում, եզրային գործառույթներ, զննարկիչի վրա հիմնված մշակում), ստիպված են նույն հայեցակարգի համար ձեռնամուխ լինել երկու անհամատեղելի աբստրակցիա:
Ինչպիսի՞ն կարող է լինել ավելի լավ Streams API-ն
Մի քանի առաջարկներ և համայնքային փորձեր մատնանշում են ավելի հարմար ապագա մշակողների համար: Հիմնական գաղափարները շարունակում են համընկնել մի քանի սկզբունքների վրա. Պատկերացրեք, որ կարող եք հոսքային տվյալների խողովակաշարեր գրել նույնքան բնական, որքան զանգվածների փոխակերպումները գրում եք՝ շղթայելով .map(), .filter() և .take() ուղղակիորեն ընթեռնելի հոսքի վրա՝ առանց միջանկյալ TransformStream օբյեկտներ կառուցելու անհրաժեշտության:
Սա հիպոթետիկ չէ: Iterator Helpers առաջարկը (այժմ TC39-ի 4-րդ փուլում) արդեն իսկ բերում է .map(), .filter(), .take(), .drop() և .flatMater>. Այս օրինաչափության ընդլայնումը ոչ համաժամեցվող կրկնողներին, և ընդարձակմանը, ընթեռնելի հոսքերին, որոնք բացահայտում են [Symbol.asyncIterator]-ը, բնական հաջորդ քայլ է: Որոշ գործարկման ժամանակներ և գրադարաններ արդեն սկսել են փորձարկել այս մոտեցումը, թույլ տալով, որ մշակողները գրեն կոդ, ինչպիսին է՝
Ամենահզոր հոսքային աբստրակցիան այն է, որն անհետանում է: Երբ մշակողները կարող են արտահայտել տվյալների փոխակերպումները որպես պարզ գործառույթների շղթա՝ առանց անհանգստանալու կարգավորիչների, հերթագրման ռազմավարությունների կամ ձեռքով հետադարձ ճնշման մասին, նրանք ավելի արագ են կառուցում, ավելի քիչ սխալներ են ուղարկում և իրականում հաճույք են ստանում հոսքային տվյալների հետ աշխատելուց:
Նպատակը ցածր մակարդակի Streams API-ն ամբողջությամբ փոխարինելը չէ: Միշտ կլինեն օգտագործման դեպքեր՝ հատուկ արձանագրություններ, մանրահատիկ հիշողության կառավարում, երկուական կոդեկների ներդրում, որտեղ վերահսկիչի անմիջական մուտքն էական է: Բայց օգտագործման դեպքերի 90%-ի համար, որոնք ներառում են հաջորդական տվյալներ կարդալու, փոխակերպելու և գրելու համար, աբստրակցիոն շերտը պետք է համապատասխանի առաջադրանքի պարզությանը:
Դասեր այլ էկոհամակարգերից
JavaScript-ը առաջին լեզուն չէ, որը պայքարում է հոսքային էրգոնոմիկայի հետ: Rust-ի Iterator և Stream հատկանիշներն առաջարկում են բաղադրելի, զրոյական ծախսերի վերացականություն, որը թույլ է տալիս ծրագրավորողներին շղթայել գործողությունները՝ առանց միջանկյալ հավաքածուներ հատկացնելու: Elixir-ի Stream մոդուլն ապահովում է ծույլ թվարկում մաքուր, խողովակների համար հարմար շարահյուսությամբ: Նույնիսկ Java-ն, որը հաճախ քննադատվում է խոսակցականության համար, Java 8-ում ներմուծեց java.util.stream.Stream սահուն API-ով, որը JavaScript-ի մշակողները կճանաչեին և կնախանձեին:
Այն, ինչ կիսում են այս էկոհամակարգերը, պարտավորություն է ընդհանուր գործը չնչին դարձնելու: Ֆայլի ընթերցումը, տողերի զտումը և արդյունքները գրելու համար պահանջվում է 3-5 տող կազմվող կոդ: JavaScript-ի ընթացիկ Streams API-ում նույն գործողությունը կարող է հեշտությամբ ընդլայնվել մինչև 20-30 տող, երբ հաշվի եք առնում հոսքի կառուցումը, սխալների մշակումը և պատշաճ հեռացումը: Բացը հնարավորությունների մասին չէ, այլ էրգոնոմիկայի:
Python-ի մոտեցումը նույնպես ուսանելի է։ yield-ով գեներատորի գործառույթները բնական ճանապարհ են ապահովում հաջորդական տվյալներ ծուլորեն արտադրելու և սպառելու համար: JavaScript-ն ունի նաև գեներատորի գործառույթներ, սակայն դրանք Streams API-ի հետ կամրջելու համար պահանջվում է դրանք փաթաթել ReadableStream կոնստրուկտորներով՝ pull-ի վրա հիմնված կարգավորիչներով: Գեներատորների և հոսքերի միջև ավելի խստացված ինտեգրումը, որտեղ գեներատորի գործառույթը կարող է ուղղակիորեն դառնալ ընթեռնելի հոսք, կվերացնի կաթսայի մի ամբողջ կատեգորիա:
Իրական աշխարհի ազդեցությունը հավելվածների մշակման վրա
Սա ակադեմիական մտահոգություն չէ: Հոսքային տվյալները ժամանակակից վեբ հավելվածների հիմքում են: Սերվերի կողմից ուղարկված իրադարձություններ, HTTP-ի մասնատված պատասխաններ, իրական ժամանակի վերլուծական վահանակներ, ֆայլերի վերբեռնման մշակում, AI մոդելի ելքային հոսք. սրանք ամենօրյա գործառույթներ են, ոչ թե եզրային դեպքեր: Երբ հոսքային պրիմիտիվը դժվար է օգտագործել, մշակողները կամ ամբողջովին խուսափում են դրանից (ամեն ինչ բուֆերացնում են հիշողության մեջ, որը մասշտաբային չէ) կամ կառուցում են փխրուն, դժվար պահպանվող խողովակաշարեր, որոնք դառնում են արտադրության միջադեպերի աղբյուր:
Մտածեք, թե ինչ է տեղի ունենում մասշտաբով: Նման հարթակը, ինչպիսին է Mewayz-ը, որը մշակում է տվյալներ 207 ինտեգրված բիզնես մոդուլների վրա՝ սկսած CRM խողովակաշարերից և հաշիվ-ապրանքագրերից մինչև աշխատավարձի հաշվարկներ և նավատորմի հետագծում, վերահսկում է ահռելի ծավալի հաջորդական տվյալներ ներսում: Արտահանման գործառնությունները, հաշվետվությունների ստեղծումը, webhook-ի իրադարձությունների մշակումը և վահանակի իրական ժամանակի թարմացումները բոլորն օգտվում են արդյունավետ հոսքից: Երբ հիմքում ընկած լեզվական պարզունակությունը դժվարացնում է հոսքը, արժեքը բազմապատկվում է յուրաքանչյուր մոդուլի և տվյալների յուրաքանչյուր հոսքի վրա: Պլատֆորմի ինժեներները վերջում կառուցում են ներքին հոսքային աբստրակցիաներ լեզվի աբստրակցիաների վրա՝ ավելացնելով բարդություն, որը չպետք է անհրաժեշտ լինի:
💡 DID YOU KNOW?
Mewayz replaces 8+ business tools in one platform
CRM · Invoicing · HR · Projects · Booking · eCommerce · POS · Analytics. Free forever plan available.
Start Free →- Ֆայլերի մշակում. 100K+ տողերով CSV ֆայլեր վերբեռնելու և վերլուծելու համար անհրաժեշտ է հոսքային հոսք՝ հիշողության սպառումը խուսափելու համար, սակայն ներկայիս API-ն նույնիսկ տող առ տող տրանսֆորմացիայի հիմնական է դարձնում
- Իրական ժամանակի վահանակներ․
- AI պատասխանի հոսք․ Քանի որ LLM-ով աշխատող գործառույթները դառնում են ստանդարտ բիզնես գործիքների մեջ, UI-ին տոկեն առ նշան պատասխանների հոսքը ելակետային ակնկալիք է և կատարյալ օգտագործման դեպք շղթայական հոսքերի փոխակերպումների համար
- Խմբաքանակային գործառնություններ. հազարավոր աշխատակիցների աշխատավարձերի մշակումը, մեծաքանակ հաշիվ-ապրանքագրերի ստեղծումը կամ CRM գրառումների համաժամացումը արտաքին համակարգերի հետ բոլորը ներառում են տվյալների հոսք՝ վավերացման, փոխակերպման և ելքային փուլերի միջոցով
- Webhook խողովակաշարեր․
Ի՞նչ է իրականում առաջարկվում
JavaScript-ի էկոհամակարգը շարժվում է բազմաթիվ ճակատներով: TC39 Iterator Helpers առաջարկն արդեն հայտնվել է՝ ֆունկցիոնալ կազմը բերելով համաժամանակյա կրկնողներին: Բնական ընդլայնումը — Async Iterator Helpers — կբերի նույն .map(), .filter(), .reduce(), .take() և .flatMap()-ը, որոնք արդեն ընթեռնելի են vincater-ի համար: [Symbol.asyncIterator]: Սա միայն կտրուկ կբարելավի ծրագրավորողների փորձը ամենատարածված հոսքային օրինաչափությունների համար:
TC39-ից այն կողմ, գործարկման մակարդակի նորարարությունները նույնպես առաջ են մղում սահմանը: Deno-ն փորձարկել է ավելի էրգոնոմիկ հոսքային կոմունալ ծառայություններ: Web Streams Toolbox-ը և համանման համայնքային գրադարանները տրամադրում են օգնական գործառույթներ, որոնք փաթաթում են API-ի մանրամասն մասերը: Եվ աճող թափ կա հոսքի հայրենի ստանդարտ գրադարանի գաղափարի հետևում. ներկառուցված, օպտիմիզացված կոմունալ ծառայությունների մի շարք ընդհանուր հոսքային գործառնությունների համար, ինչպիսիք են տողերի բաժանումը, JSON վերլուծությունը, CSV մշակումը և սեղմումը, որոնք մշակողները ներկայումս օգտագործում են npm-ից:
Կա նաև համոզիչ փաստարկ ավելի լավ սխալի իմաստաբանության համար: Այսօրվա API-ում խողովակային շղթայում սխալը կարող է թողնել հոսքերը երկիմաստ վիճակներում՝ մասամբ սպառված՝ կախված կողպեքներով ընթերցողների վրա: Վերանայված API-ն կարող է ընդունել կառուցվածքային սխալների տարածում, որը նման է Rust-ի Result տիպին կամ ընդունել կոնվենցիա, որտեղ սխալները հոսում են խողովակաշարի միջով որպես արժեքներ՝ թույլ տալով ներքևող փուլերին կարգավորել կամ վերականգնել դրանցից՝ առանց խախտելու ամբողջ շղթան: Սա փոխակերպող կլինի արտադրության հուսալիության համար:
Ինչու է սա ավելի քան երբևէ կարևոր 2026 թվականին
Երեք համընկնող միտումները այժմ ավելի հրատապ են դարձնում հոսքային API-ի էրգոնոմիկան, քան JavaScript-ի պատմության ցանկացած պահի: Նախ, եզրային հաշվարկը - Cloudflare Workers, Vercel Edge Functions, Deno Deploy - գործում է հիշողության և պրոցեսորի խիստ սահմանափակումների ներքո, որտեղ ամբողջական պատասխանների կամ տվյալների հավաքածուների բուֆերավորումը պարզապես կենսունակ չէ: Streaming-ը միակ տարբերակն է, և այս միջավայրերում տեղակայող մշակողները կարիք ունեն API, որը չի պայքարում դրանց դեմ:
Երկրորդ, AI ինտեգրումը դարձրել է հոսքը օգտատերերի դեմ առնչվող գործառույթ: Երբ AI օգնականը պատասխան է ստեղծում, օգտվողներն ակնկալում են տեսնել, որ նշանները կհայտնվեն իրական ժամանակում, այլ ոչ թե սպասեն, որ ամբողջ պատասխանը բուֆերանա: SaaS-ի յուրաքանչյուր հարթակ՝ բիզնեսի օպերացիոն համակարգերից, ինչպիսիք են Mewayz-ը մինչև ինքնուրույն AI գործիքներ, այժմ կարիք ունի հաճախորդի կողմից հոսքի կայուն սպառման: Ընթացիկ API-ն աշխատում է դրա համար, սակայն մշակողների փորձը՝ վերլուծելու, փոխակերպելու և հոսքային AI-ի ելքը ցուցադրելու համար, կարող է զգալիորեն ավելի լավ լինել կոմպոզիտորական հոսքի օպերատորների դեպքում:
Երրորդ, ամբողջական կույտ JavaScript շարժումը նշանակում է, որ մշակողները կառավարում են հոսքերը ցանցի սահմանի երկու կողմերում: Մեկ ինժեներ կարող է գրել սերվերի կողմից հոսք, որը մշակում է տվյալների բազայի հարցումների արդյունքները, դրանք փոխանցում է փոխակերպման, ուղարկում դրանք որպես HTTP-ի պատասխան, և այնուհետև սպառում է այդ նույն հոսքը հաճախորդի վրա՝ առաջադեմ միջերես տրամադրելու համար: Երբ հոսքային API-ն անհարմար է, այդ շփումը զգացվում է կույտի յուրաքանչյուր շերտում:
Շարժվելով առաջ. ինչ կարող են անել մշակողները այսօր
Մինչ լեզուն զարգանում է, մշակողները չեն սպասում: Մի քանի գործնական ռազմավարություններ կարող են բարելավել հոսքային փորձը ընթացիկ նախագծերում: Օգտագործելով async գեներատորները որպես առաջնային հեղինակային օրինաչափություն, և դրանք փաթաթելով ReadableStream.from()-ում, որտեղ գործարկման ժամանակը աջակցում է դրան, ապահովում է շատ ավելի մաքուր շարահյուսություն, քան կարգավորիչի ձեռքով կառավարումը: Գրադարանները, ինչպիսիք են it-pipe-ը և streaming-iterables-ը, առաջարկում են կոմպոզիտային օգնականներ, որոնք այսօր ֆունկցիոնալ շղթայով են բերում համաժամեցված կրկնողներին:
Տվյալների ինտենսիվ հավելվածներ ստեղծող թիմերի համար ներդրումները ներքին հոսքային բարակ օգտակար շերտում շահաբաժիններ են տալիս: Լավ նախագծված streamMap(), streamFilter() և streamBatch() գործառույթների շարքը, որոնցից յուրաքանչյուրը վերցնում է համաժամանակյա կրկնվող և վերադարձնում է համաժամանակյա կրկնվողը, ապահովում է այն կոմպոզիցիան, որը չունի ստանդարտ API-ն՝ առանց ամբողջական հոսքային շրջանակի ծանրության: Սա այն օրինաչափությունն է, որը ընդլայնվում է նորաստեղծ նախատիպերից մինչև միլիոնավոր գործողություններ կատարող հարթակներ:
- Ընդունեք async գեներատորներ որպես հոսքային տվյալների արտադրության ձեր լռելյայն օրինաչափություն. դրանք ավելի մաքուր են, ավելի փորձարկվող և ավելի բաղադրելի, քան ձեռքով ReadableStream կառուցումը
- Օգտագործեք
ReadableStream.from()՝ համաժամեցված կրկնվող թվերը վեբ հոսքերի աշխարհում կամրջելու համար, երբ Ձեզ անհրաժեշտ է փոխգործակցել ReadableStream-ի օրինակներ սպասող API-ների հետ - Կառուցեք կամ կիրառեք բարակ օգտակար գործառույթներ սովորական գործողությունների համար (քարտեզ, զտիչ, խմբաքանակ, շնչափող) ոչ թե TransformStream-ի օբյեկտներ կառուցելու փոխարեն, ոչ թե ոչ թե TransformStream-ի, այլ ոչ համաժամանակյա կրկնվող թվերի վրա:
- Փաստաբան TC39-ի և գործարկման ժամանակի քննարկումներում — համաժամեցված կրկնող օգնականների առաջարկին անհրաժեշտ են ծրագրավորողների ձայներ, որոնք առաջնահերթություն են պահանջում
- Գրեք թեստեր համաժամանակյա կրկնվողների դեմ, այլ ոչ թե ուղիղ հեռարձակումներ. սա ձեր հոսքային տրամաբանությունը դարձնում է շարժական և ավելի հեշտ վավերացնելը
JavaScript Streams API-ն անհրաժեշտ հիմք էր: Բայց հիմքերը պետք է կառուցվեն, և աբստրակցիայի հաջորդ շերտը, որը հոսքը դարձնում է նույնքան բնական, որքան զանգվածների հետ աշխատելը, ուշացած է: Կտորները տեղում են՝ համաժամեցված կրկնիչներ, գեներատորի ֆունկցիաներ և կրկնող օգնականների օրինաչափություն: Այժմ անհրաժեշտ է հավաքական կամք՝ դրանք հավաքելու ստանդարտի մեջ, որը կհամապատասխանի այն, թե ինչպես են իրականում մշակողները մտածում հաջորդական տվյալների մասին: Արդյունքը ոչ միայն կլինի ավելի լավ API, այլ այն կբացի հեռարձակումը որպես լռելյայն օրինակ, այլ ոչ թե որպես վերջին միջոց՝ դարձնելով հավելվածներն ավելի արագ, ավելի արդյունավետ հիշողության համար և ավելի հաճելի՝ կառուցելու համար:
Հաճախակի տրվող հարցեր
Ի՞նչն է սխալ ներկայիս JavaScript Streams API-ի հետ:
Ընթացիկ Streams API-ն տառապում է չափից ավելի կաթսայատից, շփոթեցնող հետճնշման իմաստաբանությունից և չափազանց բարդ API մակերեսից, որը խոչընդոտում է ընդունումը: Պարզ առաջադրանքները, ինչպիսիք են ֆայլը կարդալը կամ HTTP պատասխանի մշակումը, պահանջում են շատ ավելի շատ կոդ, քան անհրաժեշտ է: Մշակողները հաճախ դիմում են երրորդ կողմի գրադարաններին կամ ավելի հին օրինաչափություններին, ինչպիսիք են հետադարձ զանգերը և իրադարձությունների արտանետումները՝ ամբողջությամբ շրջանցելով ստանդարտը, քանի որ էրգոնոմիկան ավելի մոտ է թվում ձեռնարկատիրական Java-ին, քան ժամանակակից JavaScript-ին:
Ինչպե՞ս ավելի լավ Streams API-ն կբարելավի վեբ զարգացումը:
Վերանախագծված Streams API-ն ավելի մաքուր շարահյուսությամբ, ներկառուցված համաժամացման կրկնության աջակցությամբ և ինտուիտիվ կոմպոզիցիայի մեթոդներով զգալիորեն կպարզեցնի իրական ժամանակի տվյալների մշակումը: Մշակողները կարող էին շղթայական փոխակերպումներ կատարել բնական ճանապարհով, թափանցիկ կերպով կարգավորել հետադարձ ճնշումը և գրել հոսքային խողովակաշարեր կոդի մի մասում: Սա կդարձնի առաջադեմ արտապատկերումը, կենդանի տվյալների հոսքերը և մեծ ֆայլերի մշակումը հասանելի JavaScript-ի յուրաքանչյուր մշակողի համար, ոչ միայն նրանց, ովքեր ցանկանում են պայքարել ցածր մակարդակի պարզունակության հետ:
Կարո՞ղ են ժամանակակից բիզնես հարթակները արդյունավետ կերպով վարել իրական ժամանակի տվյալների հոսքը:
Այո, այնպիսի հարթակներ, ինչպիսին է Mewayz-ը, 207 մոդուլից բաղկացած բիզնես ՕՀ, որը սկսվում է $19/ամսից, արդեն իսկ օգտագործում են արդյունավետ տվյալների խողովակաշարեր կուլիսներում վերլուծության, ավտոմատացման աշխատանքային հոսքերի և կենդանի հաշվետվությունների համար: Քանի որ հոսքային ստանդարտները բարելավվում են JavaScript-ում, վեբ փաթեթում կառուցված գործիքները իրական ժամանակում ավելի արագ փորձառություններ կհաղորդեն՝ սկսած վահանակի ակնթարթային թարմացումներից մինչև ֆայլերի անխափան մշակում ինտեգրված բիզնես մոդուլների միջոցով:
Ի՞նչ այլընտրանքներ կան, մինչ Streams API-ն զարգանում է:
Ներկայումս մշակողները հիմնվում են գրադարանների վրա, ինչպիսիք են Node.js հոսքերը, RxJS-ը ռեակտիվ ծրագրավորման համար, կամ համաժամեցված գեներատորները, որոնք զուգակցված են սպասման օղակների հետ՝ հաջորդական տվյալները ավելի էրգոնոմիկ կերպով մշակելու համար: Վեբ-համատեղելի polyfill-ները և առաջարկի փուլի օգնականները նույնպես կամրջում են ստանդարտ API-ի բացերը: Հիմնական բանը աբստրակցիաների ընտրությունն է, որոնք համընկնում են ձեր օգտագործման դեպքի հետ, լինի դա նկատի ունենալով դիտելի օրինաչափություններ իրադարձությունների ծանրաբեռնված հավելվածների համար, թե պարզ ասինքնացված կրկնություն տվյալների փոխակերպման պարզ առաջադրանքների համար:
We use cookies to improve your experience and analyze site traffic. Cookie Policy