-
-
Notifications
You must be signed in to change notification settings - Fork 648
Promise.PSD
Dexie.Promise.newPSD (function () { // Create a PSD scope
Dexie.Promise.PSD.promiseSpecificVariable = 3; // Put something in it.
new Dexie.Promise(function (resolve, reject) { // Create a promise that uses it
setTimeout(resolve, 1000);
}).then (function () { // then() will have same PSD as Promise constructor
assert (Dexie.Promise.PSD.promiseSpecificVariable == 3);
});
});
Analogous to Thread-specific data, Promise-specific data contains static data bound to the execution flow of a Promise.
In the threading world, reentrant mutexes / recursive locking is an important pattern that enables one function to lock a mutex, then call other sub functions that also locks the same mutex without a deadlock arising. PSD makes that pattern possible in the Promise world.
Other usage samples includes anything that Thread-specific data is usable for.
In Dexie, PSD is used for:
- Maintaining transaction scopes
- Enabling reentrant write-locks on transactions
- Enabling subscribers to db.on('ready') work on db before db.open() completes
Difference Between Thread-specific data and PSD
Thread-specific Data is one-dimentional. You can set Thread-static property that will be set for the currently running thread. PSD is a tree (or stack on most cases) where each new Promise instance will create its own frame that will derive from its parent. This makes PSD data automatically disappear when a Promise goes out of scope. This is also nescessary since Promise chains (unlike threads) can all root down the the same promise but be forked on certain frames.
PSD is Dexie-proprietary invention and is not standardized in any Promise specificatotion.
Dexie.Promise.newPSD(function() {
// In this function, we have a Dexie.Promise.PSD to work with.
Dexie.Promise.PSD.myVar = 3;
new Dexie.Promise(function(resolve, reject){
// Promise constructor will derive from current scope:
alert (Dexie.Promise.PSD.myVar); // Will alert "3"
// Let's resolve the promise to explain the then() method:
setTimeout(resolve, 100);
}).then (function(){
// Here, we have the same PSD as when Promise instance was created
alert (Dexie.Promise.PSD.myVar); // Will alert "3"
}).catch (function() {
alert (Dexie.Promise.PSD.myVar); // Would alert "3" as well
});
});
alert (Dexie.Promise.PSD); // Will alert "null" (unless the code was called from another Promise)
In case calling Dexie.Promise.newPSD() when already in a PSD scope (Dexie.Promise.PSD !== null), the new PSD will derive prototypically from the outer PSD scope.
//
// top-level: Dexie.Promise.PSD === null
//
Dexie.Promise.newPSD(function() {
//
// Root-scope:
//
// Play with PSD:
Dexie.Promise.PSD.myVar = 3;
alert (Dexie.Promise.PSD.myVar); // Will alert ("3") (obviously)
Dexie.Promise.newPSD(function() {
//
// Sub-scope: Current PSD derives from parent PSD.
//
// Play with PSD: Override myVar but dont change parent value:
Dexie.Promise.PSD.myOtherVar = 18;
alert (Dexie.Promise.PSD.myVar); // Will alert ("3") (derived value)
alert (Dexie.Promise.PSD.myOtherVar); // Will alert ("18") (direct value)
});
// Back to root scope:
alert (Dexie.Promise.PSD.myOtherVar); // Will alert ("null")
alert (Dexie.Promise.PSD.myVar); // Will alert ("3")
});
// At this point, Dexie.Promise.PSD === null again.
Dexie.js - minimalistic and bullet proof indexedDB library