JS Callbacks and Promises

JS Callbacks

Callback Functions

болон

JavaScript Promises

Агуулга

  • Callback functions
  • setTimeout & setInterval
  • Callback Hell
  • Promise гэж юу вэ?
  • Promise-н төлөв
  • Promise chaining
  • Parallel Promises

Callback Functions

  • Функцэд параметр болгон дамжуулж буй функц
  • Асинхрон үйлдэл дууссаны дараа дуудагдана
  • JavaScript-д өргөн хэрэглэгддэг

Энгийн Callback жишээ

function greeting(name) {
    console.log(`Сайн байна уу, ${name}!`);
}

function processUserInput(callback) {
    const name = "Болд";
    callback(name);
}

processUserInput(greeting);  // Гаралт: "Сайн байна уу, Болд!"

setTimeout Function

console.log("Эхлэх...");

setTimeout(() => {
    console.log("3 секундын дараа!");
}, 3000);  // 3000ms = 3 секунд

console.log("Төгсөх...");

Гаралт:

"Эхлэх..."
"Төгсөх..."
// 3 секундын дараа:
"3 секундын дараа!"

setInterval жишээ

let count = 0;
const intervalId = setInterval(() => {
    count++;
    console.log(`${count} секунд өнгөрлөө`);

    if (count >= 5) {
        clearInterval(intervalId);  // Зогсоох
        console.log("Дууслаа!");
    }
}, 1000);

Практик жишээ - Файл уншиж бичих

function readFile(path, callback) {
    // Файл уншиж байгаа дүрслэл
    setTimeout(() => {
        const content = "Файлын агуулга";
        callback(null, content);
    }, 2000);
}

function processContent(content, callback) {
    // Контент боловсруулж байгаа дүрслэл
    setTimeout(() => {
        const processed = content.toUpperCase();
        callback(null, processed);
    }, 1000);
}

function saveFile(content, callback) {
    // Файл хадгалж байгаа дүрслэл
    setTimeout(() => {
        console.log("Файл хадгалагдлаа");
        callback(null, true);
    }, 1500);
}

Callback Hell

readFile('input.txt', (error, content) => {
    if (error) {
        console.error('Уншихад алдаа:', error);
        return;
    }
    processContent(content, (error, processed) => {
        if (error) {
            console.error('Боловсруулахад алдаа:', error);
            return;
        }
        saveFile(processed, (error, success) => {
            if (error) {
                console.error('Хадгалахад алдаа:', error);
                return;
            }
            console.log('Амжилттай дууслаа!');
        });
    });
});

Callback Hell

Callback Hell Website

callback hell

Promise-р шийдвэрлэх нь

const readFilePromise = () => {
    return new Promise((resolve, reject) => {
        readFile('input.txt', (error, content) => {
            if (error) reject(error);
            else resolve(content);
        });
    });
};

// Ашиглах
readFilePromise()
    .then(content => processContent(content))
    .then(processed => saveFile(processed))
    .then(() => console.log('Амжилттай!'))
    .catch(error => console.error('Алдаа:', error));

Promise гэж юу вэ?

  • Асинхрон үйлдлийн төлөөлөгч обьект
  • Ирээдүйд биелэх утга эсвэл алдааны мэдээлэл агуулна
  • Callback hell-с зайлсхийх боломж олгоно

Promise-н төлөв

promise state

Promise үүсгэх

const myPromise = new Promise((resolve, reject) => {
    // Асинхрон код
    if (/* амжилттай */) {
        resolve(value);
    } else {
        reject(error);
    }
});

Энгийн жишээ

const fetchData = new Promise((resolve, reject) => {
    setTimeout(() => {
        const data = { id: 1, name: 'Data' };
        resolve(data);
        // эсвэл
        // reject(new Error('Алдаа гарлаа'));
    }, 2000);
});

Promise ашиглах

fetchData
    .then(data => {
        console.log('Амжилттай:', data);
    })
    .catch(error => {
        console.error('Алдаа:', error);
    })
    .finally(() => {
        console.log('Үргэлж ажиллана');
    });

Promise chaining

fetchUserData(userId)
    .then(user => fetchUserPosts(user.id))
    .then(posts => fetchPostComments(posts[0].id))
    .then(comments => {
        console.log(comments);
    })
    .catch(error => {
        console.error('Алдаа гарлаа:', error);
    });

Parallel Promises

Promise.all()

Promise.all([
    fetch('/api/users'),
    fetch('/api/posts'),
    fetch('/api/comments')
])
.then(([users, posts, comments]) => {
    // Бүх promise амжилттай
});

Promise.race()

Promise.race([
    fetch('/api/fast'),
    fetch('/api/slow')
])
.then(firstResult => {
    // Хамгийн түрүүнд биелсэн
});

setTimeout vs Promise

setTimeout

setTimeout(() => {
    console.log("Done!");
}, 2000);

Promise

new Promise(resolve => {
    setTimeout(() => {
        resolve("Done!");
    }, 2000);
});

Дасгал 1: Timer

Тоологч үүсгэ:

  • 3 секунд хүлээгээд эхэлнэ
  • Секунд бүрт нэмэгдэнэ
  • 10-д хүрэхэд зогсоно

Дасгал 1: Timer

Тоологч үүсгэ:

  • 3 секунд хүлээгээд эхэлнэ
  • Секунд бүрт нэмэгдэнэ
  • 10-д хүрэхэд зогсоно
setTimeout(() => {
    let count = 0;
    const timer = setInterval(() => {
        count++;
        console.log(count);
        if (count >= 10) {
            clearInterval(timer);
            console.log('Дууслаа!');
        }
    }, 1000);
}, 3000);

Дасгал 2: Promise Chain

Дараах үйлдлүүдийг Promise chain ашиглан хийнэ:

  • Хэрэглэгчийн ID авах
  • Тухайн хэрэглэгчийн захиалгуудыг авах
  • Захиалгын нийт дүнг тооцох

Дасгал 2: Promise Chain

Дараах үйлдлүүдийг Promise chain ашиглан хийнэ:

  • Хэрэглэгчийн ID авах
  • Тухайн хэрэглэгчийн захиалгуудыг авах
  • Захиалгын нийт дүнг тооцох
function getUserId() {
    return new Promise(resolve => {
        setTimeout(() => resolve(12345), 1000);
    });
}

function getOrders(userId) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve([
                { id: 1, amount: 100 },
                { id: 2, amount: 200 }
            ]);
        }, 1000);
    });
}

getUserId()
    .then(userId => getOrders(userId))
    .then(orders => {
        const total = orders.reduce(
            (sum, order) => sum + order.amount, 0
        );
        console.log('Нийт дүн:', total);
    })
    .catch(error => console.error(error));

Дасгал 3: Parallel Promises

Promise.all ашиглан 3 API дуудалтыг зэрэг хийх:

  • Хэрэглэгчийн мэдээлэл
  • Сагсны мэдээлэл
  • Хүргэлтийн мэдээлэл

Бүгд амжилттай биелэх ёстой.

Дасгал 3: Parallel Promises

Promise.all ашиглан 3 API дуудалтыг зэрэг хийх:

  • Хэрэглэгчийн мэдээлэл
  • Сагсны мэдээлэл
  • Хүргэлтийн мэдээлэл

Бүгд амжилттай биелэх ёстой.

const getUser = () => new Promise(resolve =>
    setTimeout(() => resolve({ id: 1, name: 'Болд' }), 1000)
);

const getCart = () => new Promise(resolve =>
    setTimeout(() => resolve({ items: ['Бараа 1', 'Бараа 2'] }), 1500)
);

const getDelivery = () => new Promise(resolve =>
    setTimeout(() => resolve({ address: 'Улаанбаатар' }), 800)
);

Promise.all([getUser(), getCart(), getDelivery()])
    .then(([user, cart, delivery]) => {
        console.log('Бүх мэдээлэл:', { user, cart, delivery });
    })
    .catch(error => console.error('Алдаа:', error));

Дасгал 4: Error Handling

API дуудалтын алдааг шийдвэрлэх:

  • Сүлжээний алдааг илрүүлэх
  • 3 удаа дахин оролдох
  • Алдааны мэдээллийг хадгалах

Дасгал 4: Error Handling

API дуудалтын алдааг шийдвэрлэх:

  • Сүлжээний алдааг илрүүлэх
  • 3 удаа дахин оролдох
  • Алдааны мэдээллийг хадгалах
function fetchWithRetry(url, retries = 3) {
    return new Promise((resolve, reject) => {
        function attempt(attemptsLeft) {
            fetch(url)
                .then(resolve)
                .catch(error => {
                    console.log(`Үлдсэн оролдлого: ${attemptsLeft}`);

                    if (attemptsLeft === 0) {
                        reject(new Error(`Алдаа: ${error.message}`));
                        return;
                    }

                    setTimeout(() => {
                        attempt(attemptsLeft - 1);
                    }, 1000);
                });
        }

        attempt(retries);
    });
}

// Ашиглах
fetchWithRetry('https://api.example.com/data')
    .then(response => console.log('Амжилттай:', response))
    .catch(error => console.error('Эцсийн алдаа:', error));

Нэмэлт даалгаврууд

  1. Promise.race() ашиглан timeout mechanism хийх
  2. Promise.allSettled() ашиглан олон API дуудах
  3. Custom Promise үүсгэх (cancelable Promise)
  4. Promise chain-г async/await болгох
  5. Web API-тай ажиллах жишээ хийх

Баярлалаа!

Асуулт байна уу?