blog

プロミスを手書きする

- new Promise=>{resolve}) resolveは成功し、値を取り、状態をfullfilledに変更し、再度変更することはできません。 - new Promise=>{reject(...

Oct 5, 2020 · 3 min. read
シェア

まず最初に、プロミスの基本的なルールを示す必要があります:

-約束には3つの状態があります:保留、成就、拒絶。

-ペンディングは初期状態であり、フルフィルドとリジェクトに変換することができます。

-成功した場合、他の状態に移行することはできません。

-失敗時に別の状態に変換されず、不変の原因を持つこと。

- new Promise(=>{resolve(value)}) resolve for success, receive argument value, state changed to fullfilled and cannot be changed again.

- new Promise(=>{reject(reason)}) rejectは失敗で、引数reasonを受け取り、状態をrejectedに変更します。

実行関数がエラーを報告した場合、reject()を実行します。 - 実行関数がエラーを報告した場合、reject()を直接実行します。

class MyPromise{
 constructor(executor){
 //まず、ステート、resolveのパラメータ、rejectのパラメータを定義する。
 this.state='pending';
 this.value=undefined;
 this.reason=undefined;
 
 let resolve=(value)=>{
 //保留状態かどうかを判断する理由は、一度満たされた保留状態を変更できないようにするためである。
 if(this.state=='pending'){
 this.state='fulfilled' 
 this.value=value;
 }
 }
 
 let reject=(reason)=>{
 if(this.state=='pending'){
 this.state='rejected' 
 this.reason=reason;
 }
 }
 
 try{
 executor(resolve,reject)
 }catch(err){
 reject(err)
 }
 }
 
}

then

- Promise thenメソッドには2つのパラメータがあります:onFulfilled、onRejected、successにはsuccess値、failureにはfailure原因を指定します。

class MyPromise{
 constructor(executor){...}
 then(onFulfilled,onRejected){
 if(this.state=='fulfilled'){
 onFulfilled(this.value)
 }
 if(this.state=='rejected'){
 onRejected(this.reason)
 }
 }
 }

非同期実装の解決

let p1=new MyPromise((resolve,reject)=>{
 setTimeout(()=>{
 resolve(' ')
 },100)
})
p1.then((value)=>{
 console.log(value) 
},(err)=>{
 console.log(err)
})

- resolveがsetTimeoutに入っているときは、thenの状態は常に保留状態なので、resolveはthenでは全く実行されません。そのため、thenが呼び出されて状態が保留状態になったときに、successとfailureをそれぞれの配列に格納する必要があります。rejectまたはresolveが実行されたら、それらを呼び出します。

- プロミスは複数持つことができるので、同じ配列に存在します。

class MyPromise{
 constructor(executor){
 this.state = 'pending';
 this.value = undefined;
 this.reason = undefined;
 // 成功も同じ配列に格納される。
 this.onResolvedCallbacks = [];
 // 失敗はメソッド配列に格納される。
 this.onRejectedCallbacks = [];
 let resolve = value => {
 if (this.state === 'pending') {
 this.state = 'fulfilled';
 this.value = value;
 // resolveが実行されると、success配列の関数が呼び出される。
 this.onResolvedCallbacks.forEach(fn=>fn());
 }
 };
 let reject = reason => {
 if (this.state === 'pending') {
 this.state = 'rejected';
 this.reason = reason;
 // rejectが実行されると、failure配列の関数が呼び出される。
 this.onRejectedCallbacks.forEach(fn=>fn());
 }
 };
 try{
 executor(resolve, reject);
 } catch (err) {
 reject(err);
 }
 }
 then(onFulfilled,onRejected) {
 if (this.state === 'fulfilled') {
 onFulfilled(this.value);
 };
 if (this.state === 'rejected') {
 onRejected(this.reason);
 };
 // 状態が保留中の場合
 if (this.state === 'pending') {
 // onFulfilled成功配列に渡す
 this.onResolvedCallbacks.push(()=>{
 onFulfilled(this.value);
 })
 // onRejected失敗配列に渡す
 this.onRejectedCallbacks.push(()=>{
 onRejected(this.value);
 })
 }
 }
 
}
let p1=new MyPromise((resolve,reject)=>{
 setTimeout(()=>{
 resolve(' ')
 },100)
})
p1.then((value)=>{
 console.log(value) //' '
},(err)=>{
 console.log(err)
})
Read next

ネジの導入と使用

データベースドキュメントは、チームメンバーがExcelを書くことができるように設計されて、開発のその後の要件の最終的な要約は、時々データベースの設計文書を更新することを忘れますが、今、このツールを介して、反復の各バージョンは、クラスの後のドキュメントの世代の実装では、それはより多くの時間節約の努力です。

Oct 4, 2020 · 3 min read