Асинхрондуу JavaScript
Node.js ичинде колбэктер, промистер жана async/await
- окуялар циклин жана Node эмне үчүн бөгөттөлбөй турганын түшүндүрө аласың,
- колбэк стилиндеги кодду окуп-жаза аласың (жана «колбэк тозогун» тааныйсың),
- промистерди
.then()/.catch()менен колдоно аласың, async/awaitменен таза асинхрон код жаза аласың.
1. Бөгөттөөчү жана бөгөттөбөс код
Заказды алып, анан тамак даяр болгончо 20 мүнөт мешдин жанында катып калып, ошондон кийин гана башкаларга кызмат кылган ашпозчуну элестет. Бул бөгөттөө — бир жай тапшырма иштеп жатканда башка эч нерсе боло албайт.
Node.js акылдуу официант сыяктуу иштейт: тамакты мешке коюп, таймер коюп, башка столдорго кызмат кыла берет. Таймер шыңгыраганда тамакты алып келет. Бул бөгөттөбөс иш. Төмөнкү билдирүүлөрдүн иретин карачы:
const fs = require('fs');
// Node does NOT wait here - it starts the read and moves on
fs.readFile('note.txt', 'utf8', function (err, data) {
if (err) throw err;
console.log('Inside callback:', data);
});
console.log('After readFile call');
// Output:
// After readFile call
// Inside callback: Hello from the file!
After readFile call сабы акырында жазылса да биринчи басылат, анткени Node файлды күткөн жок. Файл жүктөлүп бүткөндө, Node колбэк функциясын аткарат.
2. Окуялар цикли (event loop)
Бир агым кантип көп ишти «бир убакта» кыла алат? Сыры — окуялар цикли. Сенин синхрондуу кодуң чакыруу стегинде иштейт. Жай тапшырмалар (таймерлер, файл окуу, тармак) Node фондук API’лерине берилет. Тапшырма бүткөндө, анын колбэги кезекте күтөт. Окуялар цикли ар дайым текшерет: «стек бошпу? анда кезектеги колбэкти алып аткар».
Эки кезек бар. Микротапшырмалар (чечилген промистер) кийинки макротапшырмадан (мисалы, setTimeout) мурун иштетилет. Бул ирет классикалык табышмакты түшүндүрөт:
console.log('1: start');
setTimeout(function () {
console.log('2: timeout');
}, 0);
Promise.resolve().then(function () {
console.log('3: promise');
});
console.log('4: end');
// Output:
// 1: start
// 4: end
// 3: promise
// 2: timeout
Адегенде эки синхрон сап иштейт (1, 4). Анан промис колбэги (3), анткени микротапшырмалар биринчи. Таймер колбэги (2) эң акырында.