[squeak-dev] The Trunk: Kernel-tonyg.1148.mcz

commits at source.squeak.org commits at source.squeak.org
Sun Feb 4 20:33:27 UTC 2018


David T. Lewis uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-tonyg.1148.mcz

==================== Summary ====================

Name: Kernel-tonyg.1148
Author: tonyg
Time: 31 January 2018, 11:37:21.27021 pm
UUID: 2a675301-406b-4222-9599-84358a7cc506
Ancestors: Kernel-eem.1147

Brings the Promise implementation closer to Javascript/A+ promises in two ways:
	* Resolving a Promise with another Promise causes them to be chained together
	* Resolving or Rejecting a Promise that is not pending is a no-op, like the Firefox/Chrome/etc in-browser promise implementations.
The tests have been changed in KernelTests-tonyg.331 accordingly.

=============== Diff against Kernel-eem.1147 ===============

Item was changed:
  Object subclass: #Promise
+ 	instanceVariableNames: 'value resolvers mutex state error rejecters'
- 	instanceVariableNames: 'onError value resolvers mutex state error rejectors rejecters'
  	classVariableNames: ''
  	poolDictionaries: ''
  	category: 'Kernel-Processes'!
  
+ !Promise commentStamp: 'tonyg 1/31/2018 23:34' prior: 0!
- !Promise commentStamp: 'fbs 5/17/2013 18:23' prior: 0!
  I represent the result of an asynchronous message.  Once the message is processed, I will be resolved to a value.  I am typically instantiated by invocations of #futureSend:at:args: (and not by #futureDo:atArgs:).
  
  See class-comment of FutureNode.
  
  I also implement the Promises/A+ Javascript specification. This allows you to chain my instances to perform arbitrarily complex asynchronous tasks with error handling baked in.
  
+ A Promise may be in one of three possible states: #pending, #fulfilled or #rejected. A Promise may move from #pending -> #fulfilled (by way of the resolveWith: message), or from #pending -> #rejected (by way of rejectWith:). No other state changes may occur.
+ 
+ Once #fulfilled or #rejected, a Promise's value must not change. In keeping with the major Javascript Promise implementations' interpretations of this, calls to resolveWith: or rejectWith: when a Promise is in #fulfilled or #rejected state are simply ignored - an error is not signalled. (See test cases PromiseTest testFirstResolutionWins, testCannotRejectFulfilledPromise and testCannotResolveaRejectedPromise.)!
- A Promise may be in one of three possible states: #pending, #fulfilled or #rejected. A Promise may move from #pending -> #fulfilled, or from #pending -> #rejected. No other state changes may occur. Once #fulfilled or #rejected, a Promise's value must change.!

Item was changed:
  ----- Method: Promise>>rejectWith: (in category 'resolving') -----
  rejectWith: anObject
  	"Reject this promise."
  	mutex critical: [
+ 		(state == #pending) ifTrue: [
+ 			error := anObject.
+ 			state := #rejected.
+ 			rejecters do: [:r | self evaluateRejecter: r]]]!
- 		(state == #fulfilled) ifTrue: [self error: 'Promise was already resolved'].
- 		(state == #rejected) ifTrue: [self error: 'Promise was already rejected'].
- 		error := anObject.
- 		state := #rejected.
- 		rejecters do: [:r | self evaluateRejecter: r]].!

Item was changed:
  ----- Method: Promise>>resolveWith: (in category 'resolving') -----
  resolveWith: arg
+ 	"Resolve this promise. If arg is itself a Promise, make this promise depend upon it,
+ 	as detailed in the Promises/A+ spec:
+ 		https://promisesaplus.com/#the-promise-resolution-procedure"
+ 
+ 	(arg isKindOf: Promise)
+ 		ifTrue: [
+ 			arg whenResolved: [:v | self resolveWith: v].
+ 			arg whenRejected: [:e | self rejectWith: e]]
+ 		ifFalse: [
+ 			mutex critical: [
+ 				(state == #pending) ifTrue: [
+ 					value := arg.
+ 					state := #fulfilled.
+ 					resolvers do: [:r | self evaluateResolver: r]]]]!
- 	"Resolve this promise"
- 	mutex critical: [
- 		(state == #fulfilled) ifTrue: [self error: 'Promise was already resolved'].
- 		(state == #rejected) ifTrue: [self error: 'Promise was already resolved'].
- 		value := arg.
- 		state := #fulfilled.
- 		resolvers do: [:r |
- 			self evaluateResolver: r]].!

Item was changed:
  ----- Method: Promise>>then: (in category 'monad') -----
  then: resolvedBlock
+ 	^ self then: resolvedBlock ifRejected: [:e | "Pass rejection reason along" e].!
- 	^ self then: resolvedBlock ifRejected: [:ignored | "Do nothing"].!



More information about the Squeak-dev mailing list