458 words
2 minutes
Safe Assignment Operator in JavaScript
Safe Assignment Operator (?=) في JavaScript 🚀
مقدمة
الـ Safe Assignment Operator (?=) هو feature جديد مقترح في ECMAScript وهيخلي حياتنا أسهل بكتير.
المشاكل اللي بنواجهها دلوقتي 😫
1. النستنج المعقد
try {
const response = await fetch('/api/data');
try {
const data = await response.json();
try {
await processData(data);
} catch (error) {
console.error('Error processing data:', error);
}
} catch (error) {
console.error('Error parsing JSON:', error);
}
} catch (error) {
console.error('Error fetching data:', error);
}
2. كود متكرر كتير
كل شوية بنكتب try-catch blocks، وده بيخلي الكود:
- صعب في القراية 📖
- صعب في الـ debugging 🐛
- صعب في الـ maintenance 🔧
الحل الجديد: Safe Assignment Operator 🎯
الشكل البسيط
async function getData() {
const [error, response] ?= await fetch('/api/data');
if (error) return handleError(error);
const [parseError, data] ?= await response.json();
if (parseError) return handleError(parseError);
return data;
}
مميزات متقدمة 🔥
1. التعامل مع Promise Chains
async function complexOperation() {
const [err1, result1] ?= await step1();
if (err1) return handleError(err1);
const [err2, result2] ?= await step2(result1);
if (err2) return handleError(err2);
const [err3, final] ?= await step3(result2);
return err3 ? handleError(err3) : final;
}
2. التعامل مع Multiple Errors
class CustomError extends Error {
constructor(type, message) {
super(message);
this.type = type;
}
}
async function robustOperation() {
const [error, data] ?= await riskyOperation();
if (error) {
switch(error.type) {
case 'NETWORK':
return await retryOperation();
case 'VALIDATION':
return await validateAndRetry();
default:
return handleGenericError(error);
}
}
return data;
}
3. تطبيقات متقدمة
أ. مع الـ Async Iterators
async function* processStream() {
for await (const chunk of dataStream) {
const [error, processed] ?= await processChunk(chunk);
if (!error) yield processed;
}
}
ب. مع الـ Error Aggregation
async function batchProcess(items) {
const errors = [];
const results = [];
for (const item of items) {
const [error, result] ?= await processItem(item);
if (error) {
errors.push({ item, error });
} else {
results.push(result);
}
}
return {
success: results,
failures: errors,
stats: {
total: items.length,
succeeded: results.length,
failed: errors.length
}
};
}
نصايح للاستخدام 💡
- Type Safety
type Result<T, E = Error> = [E | null, T | null];
async function typeSafeOperation(): Promise<Result<string>> {
const [error, data] ?= await riskyOperation();
return [error, data];
}
- Custom Error Handlers
const errorHandler = {
network: (error) => logAndRetry(error),
validation: (error) => showUserFriendlyMessage(error),
default: (error) => console.error(error)
};
async function smartErrorHandling() {
const [error, data] ?= await operation();
if (error) {
const handler = errorHandler[error.type] || errorHandler.default;
return handler(error);
}
return data;
}
ملاحظات مهمة ⚠️
- الفيتشر ده لسه proposal ومش موجود في JavaScript دلوقتي
- ممكن تستخدم libraries زي
await-to-js
كبديل مؤقت - لازم تفكر في الـ error types اللي هتتعامل معاها
- مش كل الحالات محتاجة Safe Assignment - ساعات الـ try-catch أوضح
Performance Considerations 🚀
// التعامل مع العمليات المتوازية
async function parallelOperation() {
const operations = [op1(), op2(), op3()];
const results = await Promise.all(
operations.map(async (op) => {
const [error, result] ?= await op;
return { error, result };
})
);
return results.filter(r => !r.error);
}