or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-functions.mdcache-management.mdfunction-memoization.mdindex.mdmethod-memoization.mdprofiling.mdweakmap-memoization.md

async-functions.mddocs/

0

# Asynchronous Functions

1

2

Specialized memoization for Node.js callback-style functions and promise-returning functions. Handles error cases, prevents caching of failed operations, and supports multiple promise handling modes for robust asynchronous operation caching.

3

4

## Capabilities

5

6

### Callback-Style Async Functions

7

8

Memoization for Node.js style callback functions where the last parameter is a callback with `(error, result)` signature.

9

10

```javascript { .api }

11

/**

12

* Enable memoization for Node.js callback-style async functions

13

* @param {boolean} async - Enable async callback handling

14

*/

15

const options = {

16

async: boolean

17

};

18

```

19

20

**Usage Examples:**

21

22

```javascript

23

const memoize = require("memoizee");

24

const fs = require("fs");

25

26

// Memoize file reading operations

27

const memoizedReadFile = memoize(fs.readFile, { async: true });

28

29

// First call - reads from disk

30

memoizedReadFile("./config.json", "utf8", (err, data) => {

31

if (err) console.error(err);

32

else console.log("File loaded:", data);

33

});

34

35

// Second call - returns cached result

36

memoizedReadFile("./config.json", "utf8", (err, data) => {

37

console.log("From cache:", data);

38

});

39

40

// Custom async function

41

function fetchUserData(userId, callback) {

42

setTimeout(() => {

43

if (userId === "invalid") {

44

callback(new Error("Invalid user ID"));

45

} else {

46

callback(null, { id: userId, name: `User ${userId}` });

47

}

48

}, 100);

49

}

50

51

const memoizedFetch = memoize(fetchUserData, { async: true });

52

53

memoizedFetch("123", (err, user) => {

54

console.log("User:", user); // Cached after first call

55

});

56

```

57

58

### Promise-Returning Functions

59

60

Memoization for functions that return promises, with configurable promise handling modes and error management.

61

62

```javascript { .api }

63

/**

64

* Enable memoization for promise-returning functions

65

* @param {boolean|string} promise - Enable promise handling with optional mode

66

*/

67

const options = {

68

promise: true | "then" | "then:finally" | "done" | "done:finally"

69

};

70

```

71

72

**Promise Handling Modes:**

73

74

- `true` or `"then"` (default): Uses `.then()` for promise resolution

75

- `"then:finally"`: Uses `.then()` and `.finally()` for promise resolution

76

- `"done"`: Uses `.done()` method (requires promise library support)

77

- `"done:finally"`: Uses both `.done()` and `.finally()` methods

78

79

**Usage Examples:**

80

81

```javascript

82

const memoize = require("memoizee");

83

84

// Basic promise memoization

85

async function fetchData(url) {

86

const response = await fetch(url);

87

return response.json();

88

}

89

90

const memoizedFetch = memoize(fetchData, { promise: true });

91

92

// First call - makes HTTP request

93

memoizedFetch("https://api.example.com/data")

94

.then(data => console.log("Fetched:", data));

95

96

// Second call - returns cached promise result

97

memoizedFetch("https://api.example.com/data")

98

.then(data => console.log("Cached:", data));

99

100

// With custom promise mode

101

const memoizedWithDone = memoize(fetchData, { promise: "done" });

102

103

// Error handling - failed promises are not cached

104

async function failingFunction(shouldFail) {

105

if (shouldFail) {

106

throw new Error("Operation failed");

107

}

108

return "Success";

109

}

110

111

const memoizedFailing = memoize(failingFunction, { promise: true });

112

113

memoizedFailing(true)

114

.catch(err => console.log("Error not cached"));

115

116

memoizedFailing(false)

117

.then(result => console.log("Success cached:", result));

118

```

119

120

### Combined Async Configuration

121

122

Using async memoization with other memoization features like cache expiration and size limits.

123

124

```javascript { .api }

125

/**

126

* Combine async support with other memoization options

127

*/

128

const combinedOptions = {

129

async: boolean, // or promise: boolean|string

130

maxAge: number, // Cache expiration in milliseconds

131

max: number, // Maximum cache entries

132

preFetch: boolean // Pre-fetch before expiration

133

};

134

```

135

136

**Usage Examples:**

137

138

```javascript

139

// Async with cache expiration

140

const memoizedWithTTL = memoize(asyncFunction, {

141

async: true,

142

maxAge: 60000, // 1 minute TTL

143

preFetch: true // Refresh cache before expiration

144

});

145

146

// Promise with size limit

147

const memoizedPromiseWithLimit = memoize(promiseFunction, {

148

promise: true,

149

max: 50, // Keep only 50 cached results

150

dispose: (result) => {

151

// Cleanup when entries are evicted

152

if (result && result.cleanup) result.cleanup();

153

}

154

});

155

156

// Async with custom normalizer for object arguments

157

const memoizedAsyncNormalized = memoize(asyncDbQuery, {

158

async: true,

159

normalizer: (args) => JSON.stringify(args[0]) // First arg is query object

160

});

161

```

162

163

## Error Handling

164

165

### Failed Operations Are Not Cached

166

167

Both async and promise modes automatically exclude failed operations from the cache:

168

169

```javascript

170

const memoize = require("memoizee");

171

172

// Callback-style: errors are not cached

173

const memoizedAsync = memoize((id, callback) => {

174

if (id === "fail") {

175

callback(new Error("Failed"));

176

} else {

177

callback(null, `Result for ${id}`);

178

}

179

}, { async: true });

180

181

// Promise-style: rejections are not cached

182

const memoizedPromise = memoize(async (id) => {

183

if (id === "fail") {

184

throw new Error("Failed");

185

}

186

return `Result for ${id}`;

187

}, { promise: true });

188

```

189

190

### Cache Events for Async Operations

191

192

Async memoized functions emit special events for monitoring:

193

194

```javascript { .api }

195

/**

196

* Async-specific cache events

197

*/

198

memoizedFunction.on("setasync", (id, callbackCount) => {

199

// Called when async result is cached

200

});

201

202

memoizedFunction.on("getasync", (id, args, context) => {

203

// Called when async result is retrieved from cache

204

});

205

206

memoizedFunction.on("deleteasync", (id, resultArray) => {

207

// Called when async cache entry is deleted

208

});

209

210

memoizedFunction.on("clearasync", (cache) => {

211

// Called when async cache is cleared

212

});

213

```

214

215

## Advanced Async Patterns

216

217

### Concurrent Request Deduplication

218

219

Multiple concurrent calls with same arguments will be deduplicated:

220

221

```javascript

222

const memoizedFetch = memoize(fetchData, { promise: true });

223

224

// These three calls will result in only one actual fetch

225

const promise1 = memoizedFetch("same-url");

226

const promise2 = memoizedFetch("same-url");

227

const promise3 = memoizedFetch("same-url");

228

229

// All three promises will resolve with the same result

230

Promise.all([promise1, promise2, promise3])

231

.then(results => {

232

// results[0] === results[1] === results[2]

233

});

234

```

235

236

### Pre-fetching for Cache Refresh

237

238

Automatically refresh cache entries before they expire:

239

240

```javascript

241

const memoizedWithPrefetch = memoize(asyncFunction, {

242

async: true,

243

maxAge: 60000, // 1 minute expiration

244

preFetch: 0.8 // Start refresh when 20% of TTL remains

245

});

246

247

// Cache will be refreshed in background when accessed near expiration

248

```

249

250

### Custom Promise Library Integration

251

252

For promise libraries that implement `.done()` method:

253

254

```javascript

255

const Bluebird = require("bluebird");

256

257

function promiseFunction() {

258

return new Bluebird((resolve) => {

259

setTimeout(() => resolve("result"), 100);

260

});

261

}

262

263

const memoized = memoize(promiseFunction, {

264

promise: "done" // Uses Bluebird's .done() method

265

});

266

```

267

268

## Performance Considerations

269

270

### Memory Usage with Async Caching

271

272

Async caching may use additional memory for managing pending operations:

273

274

```javascript

275

// Use size limits for async operations with high concurrency

276

const memoized = memoize(asyncOp, {

277

async: true,

278

max: 100, // Limit concurrent + cached operations

279

maxAge: 30000 // Clean up old entries

280

});

281

```

282

283

### Choosing Promise Modes

284

285

- **`"then"`** (default): Most compatible, but may suppress unhandled rejection warnings

286

- **`"done"`**: Preserves error handling characteristics of promise library

287

- **`"done:finally"`**: Best for libraries that support both, minimal side effects