Promiseコンストラクタには、<<非同期処理を書いた関数>>(executor)を引数として渡します.
executor関数はresolve, rejectと呼ばれる2つの関数を引数として取ります.
executor内で、非同期処理が終わった後にresolve(value)を呼ぶとthenのonfulfilled関数が呼ばれますね.
で、このresolve()が一体なんなのか、について仕様書をひっくり返してみました.
結論
resolve(), reject()はanonymous built-in function(組み込みの無名関数)
前提
Promiseを作るときは
new Promise( function(resolve, reject){ ... if(success){ resolve(value); } })
みたいな感じで作るが、
resolve, rejectの関数名は任意.(executorの引数名を変えて試してみればわかる.)
こいつらなんだ…と思い、調べてもわからぬので仕様書を読み解いた.
本論
Promiseコンストラクタの内部処理
.1. If NewTarget is undefined, throw a TypeError exception.
.......
.8. Let resolvingFunctions be CreateResolvingFunctions(promise).
.......
.11. Return promise.
http://www.ecma-international.org/ecma-262/6.0/index.html#sec-promise-executor
CreateResolvingFunctions()が関係深そう.
CreateResolvingFunctions ( promise )
......
.2. Let resolve be a new built-in function object as defined in Promise Resolve Functions (25.4.1.3.2).
......
.8. Return a new Record { Resolve: resolve, Reject: reject }.
http://www.ecma-international.org/ecma-262/6.0/index.html#sec-createresolvingfunctions
組み込みの無名関数をresolveに入れてますね、これだ.
25.4.2.Promise Resolve Functions
A promise resolve function is an anonymous built-in function ...
http://www.ecma-international.org/ecma-262/6.0/index.html#sec-promise-resolve-functions
ビンゴー!
整理
CreateResolvingFunctions ( promise )
'1. alreadyResolved = Record { value: false };
.2. resolve = (anonymous built-in) Promise Resolve Function;
'3. resolve.Promise = promise;
'4. resolve.AlreadyResolved = alreadyResolved;
'5. reject = (anonymous built-in) Promise Reject Function;
'6. reject.Promise = promise;
'7. reject.AlreadyResolved = alreadyResolved;
.8. Return Record { Resolve: resolve, Reject: reject };
もっと整理 CreateResolvingFunctions (Promise)
.2. resolve = (anonymous built-in) Promise Resolve Function;
3-4.
resolve{
Promise: promise,
AlreadyResolved: Record { value: false }; (1より)
}
'5. reject = (anonymous built-in) Promise Reject Function;
6-7.
reject{
Promise: promise;
AlreadyResolved = Record { value: false }; (1より)
}
.8. Return Record { Resolve: resolve, Reject: reject };
7.3.12 Call(F, V, [argumentsList])
'1. ReturnIfAbrupt(F);
'2. If(argumentsList == undifined){ argumentsList = ;}
'3. Error handling.
'4. Return F.[Call];
[http://www.ecma-international.org/ecma-262/6.0/index.html#sec-call]
9.2.1 [[Call]] ( thisArgument, argumentsList)
'1. Assert
'2. Error handling.
'3. callerContext = the running execution context;
'4. calleeContext = PrepareForOrdinaryCall(F, undefined);
'5. Assert
'6. OrdinaryCallBindThis(F, calleeContext, thisArgument);
'7. result = OrdinaryCallEvaluateBody(F, argumentsList);
'8. Remove calleeContext from the execution context stack and restore callerContext as the running execution context.
'9. If(result.[[type]] ==return){ return NormalCompletion(result.[[value]]);};
== return Completion{[[type]]: normal, [[value]]: result.[[value]], [[target]]:empty};
'10. ReturnIfAbrupt(result).
'11. Return NormalCompletion(undefined).
== return Completion{[[type]]: normal, [[value]]: undefined, [[target]]:empty};
9-11. // 必ず Completionが返る
If(result.[[type]] == return) return Completion{[[type]]: normal, [[value]]: result.[[value]], [[target]]:empty};
elseIf(result == abrupt completion) return result;
else return Completion{[[type]]: normal, [[value]]: undefined, [[target]]:empty};
コンストラクタのコール
'9. completion = Call(executor, undefined, «built-in Resolve F, built-in Reject F»);
-->
Call.4.
'4. Return executor.[Call];
Promise( executor )
- Error handling.
- Error handling.
- promise = OrdinaryCreateFromConstructor(NewTarget, "%PromisePrototype%", «[[PromiseState]], [[PromiseResult]], [[PromiseFulfillReactions]], [[PromiseRejectReactions]]» ).
- ReturnIfAbrupt(promise).
- promise.[[PromiseState]] = "pending";
- promise.[[PromiseFulfillReactions]] = ;
- promise.[[PromiseRejectReactions]] = ;
- resolvingFunctions = CreateResolvingFunctions(promise);
- completion = Call(executor, undefined, «resolvingFunctions.Resolve, resolvingFunctions.Reject»);
If(completion == abrupt completion){
status = Call(resolvingFunctions.Reject, undefined, «completion.value»);
ReturnIfAbrupt(status); } - Return promise;
より整理 Promise( executor )
1-2. Error handling.
'3. promise = OrdinaryCreateFromConstructor(NewTarget, "%PromisePrototype%", «PromiseState, PromiseResult, PromiseFulfillReactions, PromiseRejectReactions» ).
'4. ReturnIfAbrupt(promise).
5-7.
promise{
PromiseState: "pending",
PromiseFulfillReactions: ,
PromiseRejectReactions: ;
}
'8. resolvingFunctions = CreateResolvingFunctions(promise);
'9. completion = Call(executor, undefined, «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»);
'10.
If(completion == abrupt completion){
status = Call(resolvingFunctions.[[Reject]], undefined, «completion.[[value]]»);
ReturnIfAbrupt(status);
}
'11. Return promise;
統合と整理 Promise( executor )
1-2. Error handling.
'3. promise = OrdinaryCreateFromConstructor(NewTarget, "%PromisePrototype%", «[[PromiseState]], [[PromiseResult]], [[PromiseFulfillReactions]], [[PromiseRejectReactions]]» ).
'4. ReturnIfAbrupt(promise).
5-7.
promise{
[[PromiseState]]: "pending",
[[PromiseFulfillReactions]]: ,
[[PromiseRejectReactions]]: [];
}
'8. built-in function準備
'9. completion = Call(executor, undefined, «built-in Resolve F, built-in Reject F»);
'10.
If(completion == abrupt completion){
status = Call(built-in Reject F, undefined, «completion.[[value]]»);
ReturnIfAbrupt(status);
}
'11. Return promise;