1+ export {
2+ buildPlatform ,
3+ IPlatform
4+ } from './backburner/platform' ;
5+
6+ import {
7+ buildPlatform ,
8+ IPlatform ,
9+ } from './backburner/platform' ;
110import {
211 findItem ,
312 findTimer ,
@@ -14,7 +23,6 @@ import Queue, { QUEUE_STATE } from './backburner/queue';
1423type Timer = any ;
1524
1625const noop = function ( ) { } ;
17- const SET_TIMEOUT = setTimeout ;
1826
1927function parseArgs ( ) {
2028 let length = arguments . length ;
@@ -126,14 +134,25 @@ let autorunsCompletedCount = 0;
126134let deferredActionQueuesCreatedCount = 0 ;
127135let nestedDeferredActionQueuesCreated = 0 ;
128136
137+ export interface IBackburnerOptions {
138+ defaultQueue ?: string ;
139+ onBegin ?: ( currentInstance : DeferredActionQueues , previousInstance : DeferredActionQueues ) => void ;
140+ onEnd ?: ( currentInstance : DeferredActionQueues , nextInstance : DeferredActionQueues ) => void ;
141+ onError ?: ( error : any , errorRecordedForStack ?: any ) => void ;
142+ onErrorTarget ?: any ;
143+ onErrorMethod ?: string ;
144+ mustYield ?: ( ) => boolean ;
145+ _buildPlatform ?: ( flush : ( ) => void ) => IPlatform ;
146+ }
147+
129148export default class Backburner {
130149 public static Queue = Queue ;
131150
132151 public DEBUG = false ;
133152
134153 public currentInstance : DeferredActionQueues | null = null ;
135154
136- public options : any ;
155+ public options : IBackburnerOptions ;
137156
138157 public get counters ( ) {
139158 return {
@@ -183,49 +202,45 @@ export default class Backburner {
183202
184203 private _timerTimeoutId : number | null = null ;
185204 private _timers : any [ ] = [ ] ;
186- private _platform : {
187- setTimeout ( fn : Function , ms : number ) : number ;
188- clearTimeout ( id : number ) : void ;
189- next ( fn : Function ) : number ;
190- clearNext ( id : any ) : void ;
191- now ( ) : number ;
192- } ;
205+ private _platform : IPlatform ;
193206
194207 private _boundRunExpiredTimers : ( ) => void ;
195208
196209 private _autorun : number | null = null ;
197210 private _boundAutorunEnd : ( ) => void ;
211+ private _defaultQueue : string ;
198212
199- constructor ( queueNames : string [ ] , options : any = { } ) {
213+ constructor ( queueNames : string [ ] , options ?: IBackburnerOptions ) {
200214 this . queueNames = queueNames ;
201- this . options = options ;
202- if ( ! this . options . defaultQueue ) {
203- this . options . defaultQueue = queueNames [ 0 ] ;
215+ this . options = options || { } ;
216+ if ( typeof this . options . defaultQueue === 'string' ) {
217+ this . _defaultQueue = this . options . defaultQueue ;
218+ } else {
219+ this . _defaultQueue = this . queueNames [ 0 ] ;
204220 }
205221
206222 this . _onBegin = this . options . onBegin || noop ;
207223 this . _onEnd = this . options . onEnd || noop ;
208224
209- let _platform = this . options . _platform || { } ;
210- let platform = Object . create ( null ) ;
211-
212- platform . setTimeout = _platform . setTimeout || ( ( fn , ms ) => setTimeout ( fn , ms ) ) ;
213- platform . clearTimeout = _platform . clearTimeout || ( ( id ) => clearTimeout ( id ) ) ;
214- platform . next = _platform . next || ( ( fn ) => SET_TIMEOUT ( fn , 0 ) ) ;
215- platform . clearNext = _platform . clearNext || platform . clearTimeout ;
216- platform . now = _platform . now || ( ( ) => Date . now ( ) ) ;
217-
218- this . _platform = platform ;
219-
220225 this . _boundRunExpiredTimers = this . _runExpiredTimers . bind ( this ) ;
221226
222227 this . _boundAutorunEnd = ( ) => {
223228 autorunsCompletedCount ++ ;
229+
230+ // if the autorun was already flushed, do nothing
231+ if ( this . _autorun === null ) { return ; }
232+
224233 this . _autorun = null ;
225- this . end ( ) ;
234+ this . _end ( true /* fromAutorun */ ) ;
226235 } ;
236+
237+ let builder = this . options . _buildPlatform || buildPlatform ;
238+ this . _platform = builder ( this . _boundAutorunEnd ) ;
227239 }
228240
241+ public get defaultQueue ( ) {
242+ return this . _defaultQueue ;
243+ }
229244 /*
230245 @method begin
231246 @return instantiated class DeferredActionQueues
@@ -257,40 +272,7 @@ export default class Backburner {
257272
258273 public end ( ) {
259274 endCount ++ ;
260- let currentInstance = this . currentInstance ;
261- let nextInstance : DeferredActionQueues | null = null ;
262-
263- if ( currentInstance === null ) {
264- throw new Error ( `end called without begin` ) ;
265- }
266-
267- // Prevent double-finally bug in Safari 6.0.2 and iOS 6
268- // This bug appears to be resolved in Safari 6.0.5 and iOS 7
269- let finallyAlreadyCalled = false ;
270- let result ;
271- try {
272- result = currentInstance . flush ( ) ;
273- } finally {
274- if ( ! finallyAlreadyCalled ) {
275- finallyAlreadyCalled = true ;
276-
277- if ( result === QUEUE_STATE . Pause ) {
278- autorunsCreatedCount ++ ;
279- const next = this . _platform . next ;
280- this . _autorun = next ( this . _boundAutorunEnd ) ;
281- } else {
282- this . currentInstance = null ;
283-
284- if ( this . instanceStack . length > 0 ) {
285- nextInstance = this . instanceStack . pop ( ) as DeferredActionQueues ;
286- this . currentInstance = nextInstance ;
287- }
288- endEventCount ++ ;
289- this . _trigger ( 'end' , currentInstance , nextInstance ) ;
290- this . _onEnd ( currentInstance , nextInstance ) ;
291- }
292- }
293- }
275+ this . _end ( false ) ;
294276 }
295277
296278 public on ( eventName , callback ) {
@@ -564,6 +546,40 @@ export default class Backburner {
564546 this . _ensureInstance ( ) ;
565547 }
566548
549+ private _end ( fromAutorun : boolean ) {
550+ let currentInstance = this . currentInstance ;
551+ let nextInstance : DeferredActionQueues | null = null ;
552+
553+ if ( currentInstance === null ) {
554+ throw new Error ( `end called without begin` ) ;
555+ }
556+
557+ // Prevent double-finally bug in Safari 6.0.2 and iOS 6
558+ // This bug appears to be resolved in Safari 6.0.5 and iOS 7
559+ let finallyAlreadyCalled = false ;
560+ let result ;
561+ try {
562+ result = currentInstance . flush ( fromAutorun ) ;
563+ } finally {
564+ if ( ! finallyAlreadyCalled ) {
565+ finallyAlreadyCalled = true ;
566+
567+ if ( result === QUEUE_STATE . Pause ) {
568+ this . _scheduleAutorun ( ) ;
569+ } else {
570+ this . currentInstance = null ;
571+
572+ if ( this . instanceStack . length > 0 ) {
573+ nextInstance = this . instanceStack . pop ( ) as DeferredActionQueues ;
574+ this . currentInstance = nextInstance ;
575+ }
576+ this . _trigger ( 'end' , currentInstance , nextInstance ) ;
577+ this . _onEnd ( currentInstance , nextInstance ) ;
578+ }
579+ }
580+ }
581+ }
582+
567583 private _join ( target , method , args ) {
568584 if ( this . currentInstance === null ) {
569585 return this . _run ( target , method , args ) ;
@@ -654,7 +670,7 @@ export default class Backburner {
654670 /**
655671 Trigger an event. Supports up to two arguments. Designed around
656672 triggering transition events from one run loop instance to the
657- next, which requires an argument for the first instance and then
673+ next, which requires an argument for the instance and then
658674 an argument for the next instance.
659675
660676 @private
@@ -685,7 +701,7 @@ export default class Backburner {
685701 let timers = this . _timers ;
686702 let i = 0 ;
687703 let l = timers . length ;
688- let defaultQueue = this . options . defaultQueue ;
704+ let defaultQueue = this . _defaultQueue ;
689705 let n = this . _platform . now ( ) ;
690706
691707 for ( ; i < l ; i += 6 ) {
@@ -727,9 +743,13 @@ export default class Backburner {
727743 if ( currentInstance === null ) {
728744 autorunsCreatedCount ++ ;
729745 currentInstance = this . begin ( ) ;
730- const next = this . _platform . next ;
731- this . _autorun = next ( this . _boundAutorunEnd ) ;
746+ this . _scheduleAutorun ( ) ;
732747 }
733748 return currentInstance ;
734749 }
750+
751+ private _scheduleAutorun ( ) {
752+ const next = this . _platform . next ;
753+ this . _autorun = next ( ) ;
754+ }
735755}
0 commit comments