Basic Syntax and APIs
Module Imports and Exports
URL Import Mechanism
Deno uses a URL-based ES module system, requiring all dependencies to explicitly declare their sources. This design offers transparency and portability advantages.
// Import standard library module (with version)
import { serve } from "https://deno.land/std@0.140.0/http/server.ts";
// Import third-party module (CDN-hosted)
import lodash from "https://cdn.skypack.dev/lodash@4.17.21";
// Import local module
import { helper } from "./utils.ts";Dynamic Import Implementation
Dynamic imports allow on-demand module loading at runtime, returning a Promise:
async function loadLogger(level: string) {
let logger;
if (level === "debug") {
logger = await import("https://example.com/debug_logger.ts");
} else {
logger = await import("https://example.com/production_logger.ts");
}
return logger.getLogger();
}
// Usage example
const logger = await loadLogger("debug");
logger.log("Debug message");Module Export Specification
Deno supports all ES module export methods:
// Named export
export function add(a: number, b: number) {
return a + b;
}
// Default export
const PI = 3.14159;
export default PI;
// Mixed export
export { add };
export { PI as default };File System Operations
Basic File Reading and Writing
Deno’s file operations require explicit permissions, and all APIs return Promises:
// Asynchronous file reading
const text = await Deno.readTextFile("input.txt");
console.log(text);
// Synchronous reading (not recommended)
const textSync = Deno.readTextFileSync("input.txt");
// File writing (requires --allow-write)
await Deno.writeTextFile("output.txt", "Hello Deno!");
// Binary file operations
const data = new Uint8Array([65, 66, 67]); // ASCII: ABC
await Deno.writeFile("binary.bin", data);Advanced File System Operations
// Copy file (requires --allow-read --allow-write)
await Deno.copyFile("source.txt", "dest.txt");
// File status check
const fileInfo = await Deno.stat("file.txt");
console.log(fileInfo.size, fileInfo.mtime);
// Directory operations
// Create directory
await Deno.mkdir("new_dir", { recursive: true });
// Read directory
const entries = await Deno.readDir(".");
for await (const entry of entries) {
console.log(entry.name, entry.isFile);
}Network Programming Basics
HTTP Server Implementation
import { serve } from "https://deno.land/std@0.140.0/http/server.ts";
const server = serve({ port: 8000 });
console.log("Server running on http://localhost:8000");
for await (const req of server) {
// Handle request
req.respond({
status: 200,
body: "Hello from Deno server!"
});
}HTTP Client Requests
// GET request
const resp = await fetch("https://jsonplaceholder.typicode.com/posts/1");
const data = await resp.json();
console.log(data);
// POST request
const postData = new URLSearchParams({
title: "foo",
body: "bar",
userId: "1"
});
const postResp = await fetch("https://jsonplaceholder.typicode.com/posts", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: postData
});
console.log(await postResp.json());WebSocket Communication
// Server
import { serve } from "https://deno.land/std@0.140.0/http/server.ts";
const server = serve({ port: 8080 });
console.log("WebSocket server running on ws://localhost:8080");
for await (const req of server) {
const { conn, r: bufReader, w: bufWriter, headers } = req;
const socket = await Deno.upgradeWebSocket(conn, bufReader, bufWriter, headers);
socket.onmessage = (e) => {
console.log("Received:", e.data);
socket.send(`Echo: ${e.data}`);
};
}
// Client
const socket = new WebSocket("ws://localhost:8080");
socket.onmessage = (e) => console.log("Server:", e.data);
socket.send("Hello WebSocket!");Timers and Event Loop
Basic Timers
// setTimeout
const timeoutId = setTimeout(() => {
console.log("Timeout executed");
}, 1000);
// clearTimeout
clearTimeout(timeoutId);
// setInterval
const intervalId = setInterval(() => {
console.log("Interval tick");
}, 2000);
// clearInterval
clearInterval(intervalId);Event Loop Demonstration
console.log("Script start");
setTimeout(() => {
console.log("setTimeout");
}, 0);
Promise.resolve().then(() => {
console.log("Promise 1");
}).then(() => {
console.log("Promise 2");
});
queueMicrotask(() => {
console.log("queueMicrotask");
});
console.log("Script end");
/*
Output order:
Script start
Script end
Promise 1
queueMicrotask
Promise 2
setTimeout
*/Processes and Subprocesses
Executing External Commands
// Execute simple command
const { code } = await Deno.run({
cmd: ["echo", "Hello from subprocess"]
}).status();
console.log(`Exit code: ${code}`);
// Capture output
const process = Deno.run({
cmd: ["ls", "-la"],
stdout: "piped",
stderr: "piped"
});
const { code: exitCode } = await process.status();
if (exitCode === 0) {
const output = new TextDecoder().decode(await process.output());
console.log(output);
} else {
const error = new TextDecoder().decode(await process.stderrOutput());
console.error(error);
}Advanced Process Control
// Process with environment variables
const envProcess = Deno.run({
cmd: ["printenv"],
env: {
CUSTOM_VAR: "DenoValue"
},
stdout: "piped"
});
// Process with working directory
const cwdProcess = Deno.run({
cmd: ["pwd"],
cwd: "/tmp",
stdout: "piped"
});Permissions and Security
Configuring the Permission System
Basic Permission Flags
# File system permissions
deno run --allow-read=file.txt script.ts
deno run --allow-write=/path/to/dir script.ts
# Network permissions
deno run --allow-net=api.example.com script.ts
# Environment variable permissions
deno run --allow-env=HOME,PATH script.ts
# Combined permissions
deno run --allow-read --allow-net script.tsPermission Scope Control
# Allow network access for specific port
deno run --allow-net=127.0.0.1:8000 script.ts
# Allow all network but restrict file system
deno run --allow-net --allow-read=/tmp script.tsSandbox Mechanism Implementation
Security Isolation Features
- No permissions by default.
- All system access must be explicitly declared.
- No global object pollution (Node.js’s
__dirname, etc., are absent). - Module cache isolation.
Underlying Implementation
- Permission checks occur before system calls.
- Each permission operation has a corresponding checkpoint.
- Permission violations trigger immediate errors.
- No persistent state storage.
Security Best Practices
Applying the Principle of Least Privilege
# Bad: Over-privileged
deno run --allow-all script.ts
# Good: Precise permissions
deno run --allow-read=data.json --allow-net=api.example.com script.tsPermission Usage Checklist
- Does it need file system access? Specify exact paths.
- Does it need network access? Restrict to specific domains/ports.
- Does it need environment variables? List required variables explicitly.
- Does it need subprocess execution? Evaluate necessity.
Dynamic Permission Requests
Runtime Permission Checks
// Check current permission status
const status = await Deno.permissions.query({ name: "read" });
if (status.state === "granted") {
// Permission granted
} else if (status.state === "prompt") {
// Can request permission
const granted = await Deno.permissions.request({ name: "read" });
if (granted) {
// User granted permission
}
}
// Re-request permission
await Deno.permissions.request({ name: "net" });
// Revoke permission
await Deno.permissions.revoke({ name: "env" });Interactive Permission Example
async function checkPermission(name: string) {
const status = await Deno.permissions.query({ name });
if (status.state === "granted") return true;
console.log(`Requires ${name} permission, please confirm...`);
const granted = await Deno.permissions.request({ name });
return granted;
}
if (await checkPermission("read")) {
const content = await Deno.readTextFile("config.json");
console.log(content);
}Security Vulnerabilities and Protections
Common Security Risks
- Unsafe dependency imports.
- Excessive permission grants.
- Unvalidated user input.
- Hardcoded sensitive data.
Protection Measures
// Input validation example
function sanitizeInput(input: string) {
return input.replace(/[<>"'&]/g, "");
}
// Sensitive data handling
const sensitiveData = Deno.env.get("DB_PASSWORD");
if (sensitiveData) {
// Clear after use
Deno.env.delete("DB_PASSWORD");
}
// Dependency validation
const deps = await Deno.readTextFile("deps.ts");
if (deps.includes("http://")) {
throw new Error("Unsafe dependency source");
}Asynchronous Programming
Promise and async/await Basics
Promise Basic Usage
// Create Promise
function delay(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Use Promise
delay(1000).then(() => {
console.log("Executed after 1 second");
});
// Promise chaining
fetch("https://api.example.com/data")
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));async/await Syntax
// Basic async function
async function fetchData() {
try {
const response = await fetch("https://api.example.com/data");
const data = await response.json();
return data;
} catch (error) {
console.error("Request failed:", error);
throw error;
}
}
// Parallel execution
async function parallelTasks() {
const [user, posts] = await Promise.all([
fetch("/user").then(res => res.json()),
fetch("/posts").then(res => res.json())
]);
return { user, posts };
}Event-Driven Programming
Custom EventEmitter
class EventEmitter {
private listeners: Map<string, Function[]> = new Map();
on(event: string, listener: Function) {
if (!this.listeners.has(event)) {
this.listeners.set(event, []);
}
this.listeners.get(event)?.push(listener);
}
emit(event: string, ...args: any[]) {
this.listeners.get(event)?.forEach(listener => {
listener(...args);
});
}
off(event: string, listener: Function) {
const listeners = this.listeners.get(event);
if (listeners) {
this.listeners.set(
event,
listeners.filter(l => l !== listener)
);
}
}
}
// Usage example
const emitter = new EventEmitter();
emitter.on("message", (msg) => {
console.log("Received message:", msg);
});
emitter.emit("message", "Hello World");Node.js-Style Events
import { EventEmitter } from "https://deno.land/std@0.140.0/node/events.ts";
const stdEmitter = new EventEmitter();
stdEmitter.on("tick", () => {
console.log("Tick event");
});
setInterval(() => stdEmitter.emit("tick"), 1000);Asynchronous I/O Operations
Efficient File Handling
// Stream reading large file
const file = await Deno.open("large_file.txt", { read: true });
const reader = new BufReader(file);
let line: string;
while ((line = await reader.readLine()) !== null) {
console.log(line);
}
file.close();
// Asynchronous file copy
async function copyFile(src: string, dest: string) {
const srcFile = await Deno.open(src, { read: true });
const destFile = await Deno.open(dest, { write: true, create: true });
await Deno.copy(srcFile, destFile);
srcFile.close();
destFile.close();
}Advanced Network Operations
// HTTP client implementation
async function httpRequest(url: string, method = "GET", body?: string) {
const resp = await fetch(url, {
method,
headers: { "Content-Type": "application/json" },
body
});
if (!resp.ok) {
throw new Error(`HTTP error: ${resp.status}`);
}
return resp.json();
}
// WebSocket message handler
async function handleWebSocket(url: string) {
const socket = await WebSocket.connect(url);
socket.onmessage = (e) => {
console.log("Received message:", e.data);
socket.send(`Echo: ${e.data}`);
};
socket.onclose = () => console.log("Connection closed");
socket.onerror = (e) => console.error("Connection error:", e);
}Concurrency Control
Promise Combination Methods
// Parallel execution
async function fetchAll() {
const [user, posts] = await Promise.all([
fetch("/user").then(res => res.json()),
fetch("/posts").then(res => res.json())
]);
return { user, posts };
}
// Race execution
async function fetchFastest() {
try {
const response = await Promise.race([
fetch("/primary-api"),
fetch("/fallback-api")
]);
return response.json();
} catch (error) {
console.error("All requests failed:", error);
}
}
// Limit concurrency
async function limitedParallel(tasks: (() => Promise<any>)[], limit: number) {
const results: any[] = [];
const executing: Promise<any>[] = [];
for (const task of tasks) {
const p = task().then(res => {
results.push(res);
executing.splice(executing.indexOf(p), 1);
});
executing.push(p);
if (executing.length >= limit) {
await Promise.race(executing);
}
}
await Promise.all(executing);
return results;
}Asynchronous Error Handling
Error Handling Patterns
// Basic try-catch
async function riskyOperation() {
try {
const data = await fetch("/unstable-api");
return await data.json();
} catch (error) {
console.error("Operation failed:", error);
throw error; // Rethrow or return default
}
}
// Error boundary pattern
async function withErrorBoundary<T>(fn: () => Promise<T>, fallback: T) {
try {
return await fn();
} catch (error) {
console.error("Error boundary caught:", error);
return fallback;
}
}
// Global unhandled Promise rejection
Deno.unstable_setExitHandler((status) => {
if (status !== 0) {
console.error("Process exited abnormally:", status);
}
});Advanced Error Recovery
// Retry mechanism
async function retry<T>(
fn: () => Promise<T>,
maxAttempts = 3,
delayMs = 1000
): Promise<T> {
let lastError: Error;
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
return await fn();
} catch (error) {
lastError = error;
if (attempt < maxAttempts) {
await new Promise(res => setTimeout(res, delayMs));
}
}
}
throw lastError;
}
// Circuit breaker pattern
class CircuitBreaker {
private state: "CLOSED" | "OPEN" | "HALF_OPEN" = "CLOSED";
private failureCount = 0;
private readonly threshold: number;
private readonly resetTimeout: number;
constructor(threshold = 3, resetTimeout = 5000) {
this.threshold = threshold;
this.resetTimeout = resetTimeout;
}
async execute<T>(fn: () => Promise<T>): Promise<T> {
if (this.state === "OPEN") {
throw new Error("Circuit breaker open");
}
try {
const result = await fn();
this.failureCount = 0;
return result;
} catch (error) {
this.failureCount++;
if (this.failureCount >= this.threshold) {
this.state = "OPEN";
setTimeout(() => {
this.state = "HALF_OPEN";
}, this.resetTimeout);
}
throw error;
}
}
}Asynchronous Programming Models and Deno Runtime Features
In-Depth Analysis of Event Loop Mechanism
Deno’s event loop, built on the V8 engine, differs significantly from Node.js. It consists of six phases:
- Timers: Processes
setTimeoutandsetIntervalcallbacks. - Pending Callbacks: Executes system-level callbacks (e.g., TCP errors).
- Idle/Prepare: Internal use.
- Poll: Retrieves new I/O events.
- Check:
setImmediatecallbacks (triggered viaDeno.run, etc., in Deno). - Close Callbacks: Handles close event callbacks.
// Event loop phase demonstration
console.log("Script start"); // Synchronous code
setTimeout(() => {
console.log("setTimeout"); // Timers phase
}, 0);
Promise.resolve().then(() => {
console.log("Promise 1"); // Microtask 1
}).then(() => {
console.log("Promise 2"); // Microtask 2
});
queueMicrotask(() => {
console.log("queueMicrotask"); // Microtask 3
});
Deno.run({ cmd: ["echo", "hello"] }); // May trigger check phase callbacks
console.log("Script end"); // Synchronous code
/*
Typical output order:
Script start
Script end
Promise 1
queueMicrotask
Promise 2
setTimeout
(Possibly interspersed with Deno.run-related callbacks)
*/Microtask Queue Priority
Deno strictly prioritizes microtasks over macrotasks:
// Microtask priority verification
let order = [];
setTimeout(() => order.push("timeout"), 0);
Promise.resolve().then(() => order.push("promise"));
queueMicrotask(() => order.push("microtask"));
setTimeout(() => {
console.log(order); // Output: ["promise", "microtask", "timeout"]
}, 100);Deno-Specific Asynchronous APIs
Deno offers asynchronous APIs distinct from Node.js:
// Deno-specific asynchronous file operation
const file = await Deno.open("test.txt", { read: true });
const content = new Uint8Array(1024);
const bytesRead = await file.read(content); // Returns Promise<number>
await file.close();
// Contrast with Node.js callback style
// fs.readFile('test.txt', (err, data) => {...});Core Asynchronous Programming Patterns
Advanced Promise Usage
Optimized Promise Chaining
// Best practices for chained error handling
function fetchUserData(userId: string) {
return fetch(`/api/users/${userId}`)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error ${response.status}`);
}
return response.json();
})
.then(user => fetch(`/api/users/${user.id}/posts`))
.then(response => response.json())
.catch(error => {
console.error("Fetch failed:", error);
throw error; // Rethrow to maintain chain
});
}
// Usage example
fetchUserData("123")
.then(posts => console.log(posts))
.catch(error => console.error("Final error:", error));Promise Composition Patterns
// Promise.allSettled use case
async function batchRequests(urls: string[]) {
const results = await Promise.allSettled(
urls.map(url => fetch(url).then(res => res.json()))
);
const successful = results
.filter(result => result.status === "fulfilled")
.map(result => (result as PromiseFulfilledResult<any>).value);
const failed = results
.filter(result => result.status === "rejected")
.map(result => (result as PromiseRejectedResult).reason);
return { successful, failed };
}Asynchronous Generators and Iteration
Paginated Data with Async Generators
async function* paginatedFetcher(url: string) {
let page = 1;
while (true) {
const response = await fetch(`${url}?page=${page}`);
const data = await response.json();
if (data.items.length === 0) break;
yield* data.items;
page++;
}
}
// Usage example
(async () => {
for await (const item of paginatedFetcher("/api/items")) {
console.log(item);
}
})();Async Iterators and for-await-of
class AsyncQueue<T> {
private queue: T[] = [];
private resolveNext: ((value: T | PromiseLike<T>) => void) | null = null;
enqueue(item: T) {
if (this.resolveNext) {
const resolve = this.resolveNext;
this.resolveNext = null;
resolve(item);
} else {
this.queue.push(item);
}
}
async *[Symbol.asyncIterator]() {
while (true) {
if (this.queue.length > 0) {
yield this.queue.shift()!;
} else {
await new Promise<T>(resolve => {
this.resolveNext = resolve;
});
}
}
}
}
// Usage example
(async () => {
const queue = new AsyncQueue<number>();
setTimeout(() => queue.enqueue(1), 100);
setTimeout(() => queue.enqueue(2), 200);
for await (const item of queue) {
console.log(item);
if (item === 2) break; // Prevent infinite loop
}
})();Asynchronous Error Handling Patterns
Error Boundary Pattern
async function withErrorBoundary<T>(
fn: () => Promise<T>,
fallback: T,
errorHandler?: (error: unknown) => void
): Promise<T> {
try {
return await fn();
} catch (error) {
errorHandler?.(error);
return fallback;
}
}
// Usage example
const result = await withErrorBoundary(
() => fetch("/unstable-api").then(res => res.json()),
{ default: "data" },
error => console.error("API request failed:", error)
);Retry Mechanism Implementation
async function retry<T>(
fn: () => Promise<T>,
options: {
maxAttempts?: number;
delayMs?: number;
shouldRetry?: (error: unknown) => boolean;
} = {}
): Promise<T> {
const {
maxAttempts = 3,
delayMs = 1000,
shouldRetry = () => true
} = options;
let lastError: unknown;
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
return await fn();
} catch (error) {
lastError = error;
if (attempt < maxAttempts && shouldRetry(error)) {
await new Promise(resolve => setTimeout(resolve, delayMs));
}
}
}
throw lastError;
}
// Usage example
const data = await retry(
() => fetch("/flaky-api").then(res => res.json()),
{
maxAttempts: 5,
delayMs: 2000,
shouldRetry: error => !(error instanceof TypeError) // Skip network errors
}
);Advanced Concurrency Control Patterns
Promise Concurrency Control
Dynamic Concurrency Pool Implementation
class PromisePool {
private queue: Array<() => Promise<any>> = [];
private activeCount = 0;
constructor(private maxConcurrent: number) {}
add(task: () => Promise<any>) {
return new Promise((resolve, reject) => {
const wrappedTask = async () => {
try {
this.activeCount++;
const result = await task();
resolve(result);
} catch (error) {
reject(error);
} finally {
this.activeCount--;
this.next();
}
};
this.queue.push(wrappedTask);
this.next();
});
}
private next() {
if (this.activeCount < this.maxConcurrent && this.queue.length > 0) {
const task = this.queue.shift()!;
task();
}
}
}
// Usage example
const pool = new PromisePool(3);
const tasks = Array(10).fill(0).map((_, i) =>
() => fetch(`/api/item/${i}`).then(res => res.json())
);
await Promise.all(tasks.map(task => pool.add(task)));Priority-Based Concurrency Control
class PriorityPromisePool {
private highPriorityQueue: Array<() => Promise<any>> = [];
private lowPriorityQueue: Array<() => Promise<any>> = [];
private activeCount = 0;
constructor(private maxConcurrent: number) {}
addHighPriority(task: () => Promise<any>) {
return this.addTask(task, this.highPriorityQueue);
}
addLowPriority(task: () => Promise<any>) {
return this.addTask(task, this.lowPriorityQueue);
}
private addTask(task: () => Promise<any>, queue: Array<() => Promise<any>>) {
return new Promise((resolve, reject) => {
const wrappedTask = async () => {
try {
this.activeCount++;
const result = await task();
resolve(result);
} catch (error) {
reject(error);
} finally {
this.activeCount--;
this.next();
}
};
queue.push(wrappedTask);
this.next();
});
}
private next() {
if (this.activeCount < this.maxConcurrent) {
if (this.highPriorityQueue.length > 0) {
const task = this.highPriorityQueue.shift()!;
task();
} else if (this.lowPriorityQueue.length > 0) {
const task = this.lowPriorityQueue.shift()!;
task();
}
}
}
}Asynchronous Resource Management
Async Resource Pool Pattern
class AsyncResourcePool<T> {
private available: T[] = [];
private inUse: Set<T> = new Set();
private waiters: Array<(resource: T) => void> = [];
constructor(
private factory: () => Promise<T>,
private reset: (resource: T) => Promise<void>,
private maxSize: number
) {}
async acquire(): Promise<T> {
if (this.available.length > 0) {
const resource = this.available.pop()!;
this.inUse.add(resource);
return resource;
}
if (this.inUse.size < this.maxSize) {
const resource = await this.factory();
this.inUse.add(resource);
return resource;
}
return new Promise(resolve => {
this.waiters.push(resource => {
this.inUse.add(resource);
resolve(resource);
});
});
}
async release(resource: T) {
if (!this.inUse.has(resource)) {
throw new Error("Resource not in use");
}
this.inUse.delete(resource);
await this.reset(resource);
if (this.waiters.length > 0) {
const waiter = this.waiters.shift()!;
waiter(resource);
} else {
this.available.push(resource);
}
}
}
// Usage example
const dbConnectionPool = new AsyncResourcePool(
async () => {
console.log("Creating new connection");
return { id: Math.random() } as any;
},
async (conn) => {
console.log("Resetting connection", conn.id);
},
3
);
// Concurrent use of connection pool
await Promise.all(Array(10).fill(0).map(async () => {
const conn = await dbConnectionPool.acquire();
try {
// Use connection
console.log("Using connection", conn.id);
await new Promise(resolve => setTimeout(resolve, 1000));
} finally {
await dbConnectionPool.release(conn);
}
}));Asynchronous Programming Practical Cases
High-Performance Web Crawler Implementation
async function crawl(url: string, options: {
maxDepth: number;
concurrency: number;
delayMs: number;
}) {
const visited = new Set<string>();
const queue: Array<{ url: string; depth: number }> = [{ url, depth: 0 }];
const pool = new PromisePool(options.concurrency);
while (queue.length > 0) {
const { url, depth } = queue.shift()!;
if (depth > options.maxDepth || visited.has(url)) continue;
visited.add(url);
await pool.add(async () => {
try {
console.log("Crawling:", url);
const response = await fetch(url);
const html = await response.text();
// Parse links (simplified example)
const links = extractLinks(html);
for (const link of links) {
if (!visited.has(link)) {
queue.push({ url: link, depth: depth + 1 });
}
}
await new Promise(resolve => setTimeout(resolve, options.delayMs));
} catch (error) {
console.error("Failed to crawl:", url, error);
}
});
}
}
// Simplified link extraction function
function extractLinks(html: string): string[] {
// Actual implementation requires HTML parser
return [];
}Real-Time Data Processing Pipeline
async function createDataPipeline(
source: AsyncIterable<any>,
processors: Array<(data: any) => Promise<any>>,
sink: (data: any) => Promise<void>
) {
let currentStream = source;
// Build processing pipeline
for (const processor of processors) {
const nextStream = (async function* () {
for await (const data of currentStream) {
yield await processor(data);
}
})();
currentStream = nextStream;
}
// Consume final stream
for await (const data of currentStream) {
await sink(data);
}
}
// Usage example
(async () => {
// Simulated data source
async function* dataSource() {
for (let i = 0; i < 10; i++) {
await new Promise(resolve => setTimeout(resolve, 100));
yield { id: i, value: Math.random() };
}
}
// Processing functions
const processors = [
async (data) => ({ ...data, processed: true }),
async (data) => ({ ...data, timestamp: Date.now() })
];
// Data sink
async function sink(data) {
console.log("Processed data:", data);
}
await createDataPipeline(dataSource(), processors, sink);
})();Performance Optimization and Debugging Techniques
Asynchronous Code Performance Analysis
// Async operation performance measurement decorator
function measureAsync<T extends (...args: any[]) => Promise<any>>(
fn: T,
name: string
): (...args: Parameters<T>) => ReturnType<T> {
return async function(...args: Parameters<T>): Promise<ReturnType<T>> {
const start = performance.now();
try {
const result = await fn(...args);
const duration = performance.now() - start;
console.log(`${name} executed in ${duration.toFixed(2)}ms`);
return result;
} catch (error) {
const duration = performance.now() - start;
console.error(`${name} failed after ${duration.toFixed(2)}ms`, error);
throw error;
}
};
}
// Usage example
const fetchWithMetrics = measureAsync(
async (url: string) => {
const response = await fetch(url);
return response.json();
},
"fetchData"
);
await fetchWithMetrics("https://api.example.com/data");Asynchronous Debugging Techniques
Async Call Stack Tracing
// Enhanced async error stack
async function tracedAsync<T>(fn: () => Promise<T>, context: string) {
try {
return await fn();
} catch (error) {
if (error instanceof Error) {
error.stack += `\nAsync Context: ${context}`;
}
throw error;
}
}
// Usage example
await tracedAsync(
async () => {
await fetch("/api");
throw new Error("Test error");
},
"API request flow"
);Async Operation Visualization
// Simple async operation visualization tool
class AsyncVisualizer {
private tasks: Map<string, { start: number; end?: number }> = new Map();
start(taskName: string) {
this.tasks.set(taskName, { start: performance.now() });
}
end(taskName: string) {
const task = this.tasks.get(taskName);
if (task) {
task.end = performance.now();
}
}
print() {
console.log("Async Operations Timeline:");
for (const [name, timing] of this.tasks) {
const duration = timing.end ? timing.end - timing.start : "ongoing";
console.log(`${name}: ${duration}ms`);
}
}
}
// Usage example
const visualizer = new AsyncVisualizer();
visualizer.start("API request");
await fetch("/api").then(() => {
visualizer.end("API request");
});
visualizer.start("Data processing");
await new Promise(resolve => setTimeout(resolve, 1000));
visualizer.end("Data processing");
visualizer.print();Deno-Specific Async Patterns
Web Workers Async Communication
// Main thread code
const worker = new Worker(new URL("./worker.ts", import.meta.url).href, {
type: "module",
deno: { namespace: true }
});
worker.postMessage({ type: "calculate", data: [1, 2, 3, 4, 5] });
worker.onmessage = (e) => {
console.log("Worker result:", e.data);
};
worker.onerror = (e) => {
console.error("Worker error:", e.message);
};
// worker.ts
self.onmessage = async (e) => {
if (e.data.type === "calculate") {
// Simulate time-consuming computation
await new Promise(resolve => setTimeout(resolve, 1000));
const result = e.data.data.reduce((sum, num) => sum + num, 0);
self.postMessage({ result });
}
};Async File System Monitoring
// Use Deno.watchFs for file monitoring
const watcher = Deno.watchFs(["./data"]);
(async () => {
for await (const event of watcher) {
console.log("File system event:", event);
if (event.kind === "create") {
const content = await Deno.readTextFile(event.paths[0]);
console.log("New file content:", content);
}
}
})();
// Note: Requires --allow-read permission



