petcarescript
Version:
PetCareScript - A modern, expressive programming language designed for humans
223 lines (197 loc) • 7.02 kB
JavaScript
/**
* PetCareScript Async Library
* Async/await and Promise functionality
*/
class PCPromise {
constructor(executor) {
this.state = 'pending';
this.value = undefined;
this.handlers = [];
const resolve = (value) => {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
this.handlers.forEach(this.handle.bind(this));
this.handlers = [];
}
};
const reject = (reason) => {
if (this.state === 'pending') {
this.state = 'rejected';
this.value = reason;
this.handlers.forEach(this.handle.bind(this));
this.handlers = [];
}
};
try {
// Support both function and PetCareScript function calls
if (typeof executor === 'function') {
executor(resolve, reject);
} else if (executor && typeof executor.call === 'function') {
executor.call(null, [resolve, reject]);
}
} catch (error) {
reject(error);
}
}
handle(handler) {
if (this.state === 'pending') {
this.handlers.push(handler);
} else {
if (this.state === 'fulfilled' && handler.onFulfilled) {
handler.onFulfilled(this.value);
}
if (this.state === 'rejected' && handler.onRejected) {
handler.onRejected(this.value);
}
}
}
then(onFulfilled, onRejected) {
return new PCPromise((resolve, reject) => {
this.handle({
onFulfilled: (value) => {
if (!onFulfilled) {
resolve(value);
return;
}
try {
let result;
if (typeof onFulfilled === 'function') {
result = onFulfilled(value);
} else if (onFulfilled && typeof onFulfilled.call === 'function') {
result = onFulfilled.call(null, [value]);
}
if (result instanceof PCPromise) {
result.then(resolve, reject);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
},
onRejected: (reason) => {
if (!onRejected) {
reject(reason);
return;
}
try {
let result;
if (typeof onRejected === 'function') {
result = onRejected(reason);
} else if (onRejected && typeof onRejected.call === 'function') {
result = onRejected.call(null, [reason]);
}
if (result instanceof PCPromise) {
result.then(resolve, reject);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
}
});
});
}
catch(onRejected) {
return this.then(null, onRejected);
}
finally(onFinally) {
return this.then(
(value) => {
if (typeof onFinally === 'function') {
onFinally();
} else if (onFinally && typeof onFinally.call === 'function') {
onFinally.call(null, []);
}
return value;
},
(reason) => {
if (typeof onFinally === 'function') {
onFinally();
} else if (onFinally && typeof onFinally.call === 'function') {
onFinally.call(null, []);
}
throw reason;
}
);
}
static resolve(value) {
return new PCPromise((resolve) => resolve(value));
}
static reject(reason) {
return new PCPromise((_, reject) => reject(reason));
}
static all(promises) {
return new PCPromise((resolve, reject) => {
if (promises.length === 0) {
resolve([]);
return;
}
const results = new Array(promises.length);
let completed = 0;
promises.forEach((promise, index) => {
PCPromise.resolve(promise).then(
(value) => {
results[index] = value;
completed++;
if (completed === promises.length) {
resolve(results);
}
},
reject
);
});
});
}
static race(promises) {
return new PCPromise((resolve, reject) => {
promises.forEach((promise) => {
PCPromise.resolve(promise).then(resolve, reject);
});
});
}
}
const AsyncLib = {
// Promise implementation - export as function wrapper instead of class
Promise: (executor) => new PCPromise(executor),
// Utility functions
delay: (ms) => {
return new Promise(resolve => setTimeout(resolve, ms));
},
timeout: (promise, ms, message = 'Operation timed out') => {
const timeoutPromise = new Promise((_, reject) => {
setTimeout(() => reject(new Error(message)), ms);
});
return Promise.race([promise, timeoutPromise]);
},
// Promise helpers
resolve: (value) => Promise.resolve(value),
reject: (reason) => Promise.reject(reason),
all: (promises) => Promise.all(promises),
race: (promises) => Promise.race(promises),
// Async/await helpers
sleep: (ms) => new Promise(resolve => setTimeout(resolve, ms)),
wait: (ms) => new Promise(resolve => setTimeout(resolve, ms)),
// Concurrency helpers
parallel: async (tasks) => {
return Promise.all(tasks.map(task =>
typeof task === 'function' ? task() : task
));
},
series: async (tasks) => {
const results = [];
for (const task of tasks) {
const result = await (typeof task === 'function' ? task() : task);
results.push(result);
}
return results;
},
// Timer functions
setInterval: (fn, ms) => setInterval(fn, ms),
setTimeout: (fn, ms) => setTimeout(fn, ms),
clearInterval: (id) => clearInterval(id),
clearTimeout: (id) => clearTimeout(id)
};
module.exports = AsyncLib;