Javascript 非同期プログラミング: Promise を本当に理解していますか?

Javascript 非同期プログラミング: Promise を本当に理解していますか?

序文

非同期プログラミングでは、Promise が重要な役割を果たし、従来のソリューション (コールバック関数やイベント) よりも合理的かつ強力です。皆さんの中には、2020年なのになぜまだPromiseについて話しているのか、という疑問を持つ人もいるかもしれません。実際、友人の中には、ほぼ毎日接しているこの「古い友人」を理解している人もいるようですが、深く掘り下げてみると、多くの疑問が湧いてくるかもしれません。この記事は、この馴染みのある見知らぬ人、Promise について、より深く理解するのに役立ちます。

基本的な使い方

文法

new Promise( function(resolve, deny) {...} /* 実行者 */ )
  • Promise オブジェクトを構築するときは、executor 関数を渡す必要があり、主要なビジネス プロセスは executor 関数内で実行されます。
  • Promise コンストラクターが実行されると、executor 関数が直ちに呼び出されます。resolve 関数と deny 関数は、パラメーターとして executor に渡されます。resolve 関数と deny 関数が呼び出されると、promise の状態はそれぞれ、fulfilled または declined に変更されます。一度状態が変化すると、再び変化することはなく、いつでも結果を得ることができます。
  • executor 関数内で、resolve 関数が呼び出されると、promise.then で設定されたコールバック関数がトリガーされ、reject 関数が呼び出されると、promise.catch で設定されたコールバック関数がトリガーされます。

非同期プログラミングを管理するために Promise が使用されていることに注意してください。Promise 自体は非同期ではありません。新しい Promise が作成されると、executor 関数がすぐに実行されます。ただし、通常は executor 関数内で非同期操作を処理します。たとえば、次のコードでは、先頭に 2 が出力されます。

p1 = new Promise(()=>{とする
    タイムアウトを設定します(()=>{
      コンソール.log(1)
    },1000)
    コンソール.log(2)
  })
コンソール.log(3) // 2 3 1

Promise はコールバック関数の遅延バインディング技術を使用します。resolve 関数が実行されると、コールバック関数はまだバインドされていないため、コールバック関数の実行は延期することしかできません。これは具体的にどういう意味ですか?次の例を見てみましょう。

p1 = new Promise((resolve,reject)=>{とする
  コンソールログ(1);
  解決('波の中のボート')
  コンソール.log(2)
})
// then: 後処理の成功または失敗のメソッドを設定します p1.then(result=>{
 //p1 遅延バインディングコールバック関数 console.log('success'+result)
},理由=>{
  console.log('失敗' + 理由)
})
コンソール.log(3)
// 1
// 2
// 3
// 波の中の成功

新しい Promise が作成されると、まず executor 関数が実行され、1 と 2 が出力されます。Promise が解決されると、マイクロタスクがトリガーされるか、同期タスクが続行されます。

p1.then が実行されると、2 つの関数が格納され (この時点では、この 2 つの関数は実行されていません)、3 が出力されます。この時点で、同期タスクが完了し、最後にマイクロタスクが実行され、.then 内の成功したメソッドが実行されます。

エラー処理

Promise オブジェクトのエラーは「バブリング」の性質を持ち、onReject 関数によって処理されるか、catch ステートメントによってキャプチャされるまで返されます。この「バブリング」機能を使用すると、各 Promise オブジェクトで例外を個別にキャッチする必要がなくなります。

thenに遭遇すると、成功または失敗メソッドを実行しますが、このメソッドが現在のthenで定義されていない場合は、次の対応する関数に延期されます。

関数実行者(解決、拒否){
  rand = Math.random() とします。
  コンソール.log(1)
  console.log(ランダム)
  (ランダム > 0.5)の場合{
    解決する()
  } それ以外 {
    拒否する()
  }
}
var p0 = 新しい Promise(エグゼキュータ)
var p1 = p0.then((値) => {
  コンソールログ('成功-1')
  新しい Promise(executor) を返します
})
var p2 = p1.then((値) => {
  コンソールログ('成功-2')
  新しい Promise(executor) を返します
})
p2.catch((エラー) => {
  console.log('エラー', エラー)
})
コンソール.log(2)

このコードには、p0 ~ p2 の 3 つの Promise オブジェクトがあります。どのオブジェクトが例外をスローしたとしても、最後のオブジェクト p2.catch を使用して例外をキャッチできます。このようにして、すべての Promise オブジェクトのエラーを 1 つの関数にマージして処理できるため、各タスクが例外を個別に処理する必要があるという問題が解決されます。

この方法では、ネストされた呼び出しと頻繁なエラー処理が排除され、記述するコードはよりエレガントになり、人間の線形思考に沿ったものになります。

プロミスチェーン呼び出し

複数の Promise を連結して一連の異なるステップを表すことができることは誰もが知っています。このアプローチの鍵となるのは、Promise の次の 2 つの固有の動作です。

  • Promise で then を呼び出すたびに、新しい Promise が作成されて返され、これを連鎖させることができます。
  • then 呼び出しのフルフィルメント コールバック (最初の引数) から返される値が何であれ、その値は連鎖された Promise (最初のポイント) のフルフィルメントとして自動的に設定されます。

まず、次の例を通してこの文の意味を説明し、次にチェーン呼び出しの実行プロセスを詳しく紹介します。

p1 = new Promise((resolve, reject) => {とする
    resolve(100) // 次に実行される成功したメソッドを決定します})
// p1に接続
p2=p1とします。すると(結果=>{
    console.log('成功 1 '+結果)
    Promise.reject(1) を返す 
// 新しい Promise インスタンスを返します。これは現在のインスタンスが失敗であると判定し、次の then メソッドが実行されます}, reason=>{
    console.log('失敗 1 '+理由)
    200を返す
})
// p2に接続 
p3=p2とします。すると(結果=>{
    console.log('成功 2' + 結果)
},理由=>{
    console.log('失敗 2 '+理由)
})
// 成功 1 100
// 失敗 2 1

最初の呼び出しで作成され返されたPromise p2を、Promise.reject(1)を返すことで完了します。 p2のthen呼び出しは、実行されると、return Promise.reject(1)ステートメントから実行値を受け取ります。もちろん、p2.then は別の新しいプロミスを作成し、それを変数 p3 に格納できます。

new Promise によって生成されたインスタンスが成功するか失敗するかは、executor 関数の実行時に、resolve または reject が実行されるか、executor 関数の実行中に異常なエラーが発生するかによって異なります。どちらの場合も、インスタンスのステータスは失敗に変更されます。

then の実行時に p2 によって返される新しいインスタンスの状態によって、次の then でどのメソッドが実行されるかが決まります。状況はいくつかあります。

  • メソッドの実行が成功したか失敗したか (then の 2 つのメソッド) に関係なく、実行中に例外がスローされた場合、インスタンスのステータスは失敗に変更されます。
  • メソッド内で新しい Promise インスタンスが返される場合 (上記の例の Promise.reject(1) など)、このインスタンスを返した結果は成功または失敗となり、これによって現在のインスタンスが成功するか失敗するかが決まります。
  • 残りのケースは基本的にインスタンスを成功状態にするためのもので、前の then メソッドによって返された結果が次の then メソッドに渡されます。

別の例を見てみましょう

新しいPromise(resolve=>{
    resolve(a) // エラー // このエグゼキュータ関数の実行には例外エラーがあり、次の失敗メソッドが実行されることになります}).then(result=>{
    console.log(`成功: ${result}`)
    結果*10を返す
},理由=>{
    console.log(`失敗: ${reason}`)
// この文を実行すると、例外は発生せず、失敗した Promise インスタンスが返されるので、次の then success メソッドが実行されます // ここでは return はなく、最後に undefined が返されます
})。そして、結果=>{
    console.log(`成功: ${result}`)
},理由=>{
    console.log(`失敗: ${reason}`)
})
// 失敗: ReferenceError: a が定義されていません
// 成功: 未定義

非同期と待機

上記の例から、Promise を使用するとコールバック地獄の問題をうまく解決できるものの、このメソッドは Promise の then() メソッドでいっぱいであることがわかります。処理フローがさらに複雑な場合、コード全体が then メソッドでいっぱいになり、セマンティクスが明確でなくなり、コードが実行フローをうまく表現できなくなります。

ES7 で追加された新しい非同期プログラミング方法である async/await の実装は、Promise に基づいています。簡単に言うと、async 関数はジェネレーターの構文糖である Promise オブジェクトを返します。多くの人は、async/await が非同期操作の究極のソリューションであると考えています。

  • 構文は簡潔で、同期コードに似ており、一般的な読み方の習慣に沿っています。
  • コールバックのネストを減らすために、js での非同期操作のシリアル実行のコード編成方法を改善しました。
  • Promise ではエラーキャプチャのために try/catch をカスタマイズすることはできませんが、同期コードのように Async/await でエラーを処理することはできます。

ただし、await は非同期コードを同期コードに変換するため、いくつかの欠点もあります。複数の非同期コードに依存関係がないのに await を使用すると、パフォーマンスが低下します。

非同期関数テスト(){
  // 次のコードに依存関係がない場合は、Promise.all を使用できます // 依存関係がある場合は、実際にはコールバック地獄を解決する例です await fetch(url1)
  フェッチを待つ(url2)
  フェッチを待つ(url3)
}

次のコードを見ると、何が印刷されるかわかりますか?

p1 = Promise.resolve(1) とします。
p2 = new Promise(resolve => { とする
  タイムアウトを設定する(() => {
    解決する(2)
  }, 1000)
})
非同期関数fn() {
  コンソール.log(1)
// コードがこの行まで実行されると(この行を最初に配置)、非同期マイクロタスクを構築します // プロミスが結果を返すのを待ちます。また、以下のコード await もタスク キューにリストされます let result1 = await p2
  コンソール.log(3)
  結果2 = p1を待機します
  コンソール.log(4)
}
関数()
コンソール.log(2)
// 1 2 3 4

await の右側に表現されたロジックが promise である場合、await は promise の戻り結果を待ちます。戻り値の状態が解決された場合にのみ結果が返されます。promise が失敗状態の場合、await は戻り結果を受け取らず、await の下のコードは実行を継続しません。

p1 = Promise.reject(100) とします。
非同期関数fn1() {
  結果 = p1 を待機します
  console.log(1) //このコード行は実行されません}

もっと複雑な質問を見てみましょう。

コンソール.log(1)
タイムアウトを設定します(()=>{console.log(2)},1000)
非同期関数 fn(){
    コンソール.log(3)
    タイムアウトを設定します(()=>{console.log(4)},20)
    Promise.reject() を返す
}
非同期関数run() {
    コンソール.log(5)
    fn() を待つ
    コンソール.log(6)
}
走る()
//実行には約150ミリ秒かかります for(let i=0;i<90000000;i++){}
タイムアウトを設定します(()=>{
    コンソール.log(7)
    新しいPromise(resolve=>{
        コンソール.log(8)
        解決する()
    }).then(()=>{console.log(9)})
},0)
コンソール.log(10)
// 1 5 3 10 4 7 8 9 2

この質問をする前に、読者は次のことを理解する必要があります。

  • マイクロタスクベースのテクノロジーには、MutationObserver、Promise、および Promise に基づいて開発された他の多くのテクノロジーが含まれます。この質問では、resolve() と await fn() はどちらもマイクロタスクです。
  • マクロ タスクが到着したかどうか、または配置された順序に関係なく、メイン スレッド実行スタックが空になるたびに、エンジンはマイクロタスク キューを優先し、マイクロタスク キュー内のすべてのタスクを処理してから、マクロ タスクを処理します。

次に、段階的に分析します。

  • まず、同期コードを実行し、出力1、最初のsetTimeoutに遭遇し、そのコールバックをタスクキュー(マクロタスク)に入れて、実行を続けます。
  • run() を実行し、5 を出力して実行を続行し、await fn() に遭遇して、それをタスク キュー (マイクロタスク) に入れます。
  • await fn() 現在のコード行が実行されると、fn 関数がすぐに実行され、3 が出力されます。2 番目の setTimeout に遭遇すると、そのコールバックがタスク キュー (マクロ タスク) に入れられます。以下の await fn() のコードは、実行前に Promise 成功ステータスが返されるのを待つ必要があるため、6 は出力されません。
  • 実行を続行し、for ループ同期コードに遭遇し、150 ミリ秒待機する必要がありますが、2 番目の setTimeout は時間に達していますが実行されません。3 番目の setTimeout に遭遇し、そのコールバックをタスク キュー (マクロ タスク) に入れて、10 を出力します。 0 ミリ秒のタイマー遅延は実際には達成できないことに注意してください。 HTML5 標準によれば、setTimeOut 実行の最小遅延は 4 ミリ秒です。
  • 同期コードが実行された後、この時点でマイクロタスクが存在しない場合は、マクロタスクが実行されます。最初に前述の setTimeout が実行され、4 が出力されます。
  • 次に、次の setTimeout マクロ タスクが実行されるため、最初に 7 が出力されます。new Promise が実行されると、executor 関数がすぐに実行され、8 が出力されます。次に、resolve が実行されると、マイクロ タスクがトリガーされるため、9 が出力されます。
  • 最後に、最初のsetTimeoutマクロタスクが実行され、2が出力されます。

よく使われる方法

1. Promise.resolve()

Promise.resolve(value) メソッドは、指定された値で解決される Promise オブジェクトを返します。
Promise.resolve() は次のものと同等です。

Promise.resolve('foo')
// new Promise(resolve =>resolved('foo')) と同等

Promise.resolve メソッドのパラメータは 4 つのケースに分かれています。

(1)パラメータはPromiseインスタンスである

パラメータが Promise インスタンスの場合、Promise.resolve は変更を加えずにインスタンスをそのまま返します。

const p1 = new Promise(function (resolve, reject) {
  setTimeout(() => 拒否(新しいエラー('fail'))、3000)
})
const p2 = new Promise(function (resolve, reject) {
  タイムアウトを設定します(() => 解決します(p1), 1000)
})
2ページ目
  .then(結果 => console.log(結果))
  .catch(エラー => console.log(エラー))
// エラー: 失敗

上記のコードでは、p1 は Promise であり、3 秒後に拒否されます。 1 秒後に p2 の状態が変化し、resolve メソッドは p1 を返します。 p2 は別の Promise を返すため、p2 の状態自体は無効になり、p2 の状態は p1 の状態によって決定されます。したがって、後続のthenステートメントはすべて後者(p1)を対象とします。さらに 2 秒後、p1 は拒否され、catch メソッドで指定されたコールバック関数がトリガーされます。

(2)パラメータはthenメソッドを持つオブジェクトではない、またはオブジェクトではない

Promise.resolve("成功").then(function(値) {
 // Promise.resolve メソッドのパラメータは同時にコールバック関数に渡されます。
  console.log(値); // "成功"
}, 関数(値) {
  // は呼び出されません });

(3)パラメータなし

Promise.resolve() メソッドを使用すると、パラメータなしで呼び出して、解決された状態の Promise オブジェクトを直接返すことができます。 Promise オブジェクトを取得する場合、より便利な方法は Promise.resolve() メソッドを直接呼び出すことです。

Promise.resolve().then(関数() {
  コンソールログ('2');
});
コンソールにログ出力します。
// 1 2

(4)パラメータはthenableオブジェクトである

thenable オブジェクトは、then メソッドを持つオブジェクトを参照します。Promise.resolve メソッドは、このオブジェクトを Promise オブジェクトに変換し、その後すぐに thenable オブジェクトの then メソッドを実行します。

thenable = {
  次に: 関数(解決、拒否) {
    解決する(42);
  }
};
p1 = Promise.resolve(thenable); とします。
p1.then(関数(値) {
  console.log(値); // 42
});

2. Promise.reject()

Promise.reject() メソッドは、拒否理由を含む Promise オブジェクトを返します。

新しいPromise((resolve,reject) => {
    拒否(新しいエラー("error"));
});
// Promise.reject(new Error("Error")); と同等  

// 使用方法 Promise.reject(new Error("BOOM!")).catch(error => {
    コンソールエラー(エラー);
});

注意すべき点は、resolve または reject を呼び出した後、Promise のミッションは完了し、後続の操作は then メソッド内に配置する必要があり、resolve または reject の直後に記述してはならないことです。したがって、驚くことがないように、 return ステートメントをそれらの前に置くことをお勧めします。

新しい Promise((resolve, 拒否) => {
  拒否(1)を返す
  // 次のステートメントは実行されません console.log(2);
})

3. Promise.all()

p1 = Promise.resolve(1) とします。
p2 = new Promise(resolve => { とする
  タイムアウトを設定する(() => {
    解決する(2)
  }, 1000)
})
p3 = Promise.resolve(3) とします。
プロミス.all([p3, p2, p1])
  .then(結果 => {
 // 結果はインスタンスが配列に書き込まれた順序で返されます console.log(result) // [ 3, 2, 1 ]
  })
  .catch(理由 => {
    console.log("失敗:理由")
  })

Promise.all は新しい Promise オブジェクトを生成して返すので、Promise インスタンスのすべてのメソッドを使用できます。このメソッドは、パラメータとして渡された Promise 配列内のすべての Promise オブジェクトが解決されたときに返され、新しく作成された Promise はこれらの Promise の値を使用します。

パラメータ内のいずれかの Promise が拒否された場合、Promise.all 呼び出し全体が直ちに終了し、拒否の新しい Promise オブジェクトが返されます。

4. Promise.allSettled()

場合によっては、非同期操作の結果ではなく、これらの操作が完了したかどうかだけが重要になることがあります。このとき、ES2020 で導入された Promise.allSettled() メソッドが非常に役立ちます。この方法がなければ、すべての操作が完了したことを確認するのは面倒です。これは Promise.all() メソッドでは不可能です。

次のようなシナリオがあるとします。ページには 3 つの領域があり、それぞれが独立した 3 つのインターフェース データに対応しています。Promise.all を使用して 3 つのインターフェースを同時に要求します。いずれかのインターフェースに例外が発生すると、ステータスは拒否され、ページ内の 3 つの領域のデータが出力されなくなります。明らかに、この状況は受け入れられません。Promise.allSettled の登場により、この問題を解決できます。

Promise.allSettled([
  Promise.reject({ code: 500, msg: 'サービス例外' }),
  Promise.resolve({ コード: 200, リスト: [] }),
  Promise.resolve({ コード: 200, リスト: [] })
]).then(res => {
  コンソール.log(res)
  /*
    0: {ステータス: "拒否"、理由: {…}}
    1: {ステータス: "完了"、値: {…}}
    2: {ステータス: "fulfilled", 値: {…}}
  */
  // 拒否ステータスを除外し、ページ領域データを可能な限り多く確保する RenderContent(
    res.filter(el => {
      el.status !== '拒否' を返します
    })
  )
})

Promise.allSettled は Promise.all に似ています。Promise の配列をパラメータとして受け取り、新しい Promise を返します。唯一の違いは、短絡処理を行わないことです。つまり、すべての Promise が処理されると、正常に処理されたかどうかに関係なく、各 Promise のステータスを取得できます。

5. Promise.race()

Promise.all() メソッドの効果は「より遅く走る方がコールバックを実行する」というものなので、「より速く走る方がコールバックを実行する」ことに対応する別のメソッドが Promise.race() メソッドであり、この単語はもともとレースを意味します。 race の使用方法は all と同じで、promise オブジェクトの配列をパラメーターとして受け取ります。

Promise.all は、受信したすべてのオブジェクト プロミスが FulFilled または Rejected になるまで、後続の処理を続行しません。一方、Promise.race は、1 つのプロミス オブジェクトが FulFilled または Rejected 状態になる限り、後続の処理を続行します。

// `delay` ミリ秒後に解決を実行します
関数timerPromisify(delay) {
    新しいPromiseを返します(resolve => {
        タイムアウトを設定する(() => {
            解決(遅延)
        }、 遅れ);
    });
}
// いずれかのプロミスが解決または拒否された場合、プログラムは実行を停止します。Promise.race([
    タイマーPromisefy(1)、
    タイマー約束(32)
    タイマー約束(64)
]).then(関数 (値) {
    console.log(値); // => 1
});

上記のコードは、それぞれ 1 ミリ秒、32 ミリ秒、64 ミリ秒後に確認され、FulFilled になる 3 つの promise オブジェクトを作成し、最初のオブジェクトが確認されてから 1 ミリ秒後に .then によって登録されたコールバック関数が呼び出されます。

6. Promise.prototype.finally()

ES9 では、Promise を返す finally() メソッドが追加されました。プロミスの終了時に、それが満たされたか拒否されたかに関係なく、指定されたコールバック関数が実行されます。これにより、Promise が正常に満たされたかどうかに関係なく、実行する必要があるコードを渡す方法が提供されます。これにより、then() と catch() の両方で同じステートメントを 1 回ずつ記述する必要がある状況を回避できます。

たとえば、リクエストを送信する前には読み込み画面が表示されます。リクエストが送信された後は、リクエストにエラーがあるかどうかに関係なく、読み込み画面をオフにしたいと考えています。

this.loading = true
リクエスト()
  .then((res) => {
    // 何かをする
  })
  .catch(() => {
    // エラーをログに記録
  })
  .finally(() => {
    this.loading = false
  })

finally メソッドのコールバック関数はパラメーターを受け入れません。これは、finally メソッド内の操作が状態から独立し、Promise の実行結果に依存しないことを示します。

実用化

赤色のライトが 3 秒ごとに 1 回点灯し、緑色のライトが 1 秒ごとに 1 回点灯し、黄色のライトが 2 秒ごとに 1 回点灯するという要件があるとします。3 つのライトを交互に繰り返し点灯させるにはどうすればよいでしょうか。
すでに 3 つの照明機能が存在します。

関数 red() {
    コンソールログ('赤');
}
関数グリーン() {
    console.log('緑');
}
関数イエロー() {
    console.log('黄色');
}

この問題の複雑さは、一度点灯したら終了する 1 回限りの処理ではなく、「交互に繰り返し」点灯する必要があることにあります。これは再帰によって実現できます。

// プロミスで実装する let task = (timer, light) => {
  新しい Promise を返します ((resolve, reject) => {
    タイムアウトを設定する(() => {
      if (ライト === '赤') {
        赤()
      }
      if (ライト === '緑') {
        緑()
      }
      if (light === '黄色') {
        黄色()
      }
      解決する()
    }, タイマー);
  })
}
ステップ = () => {
  タスク(3000, '赤')
    .then(() => task(1000, 'green'))
    .then(() => task(2000, '黄色'))
    .then(ステップ)
}
ステップ()

同じことは async/await でも実現できます。

// async/await 実装 let step = async () => {
  タスクを待機します(3000, '赤')
  タスクを待機します(1000, '緑')
  タスクを待機します(2000, '黄色')
  ステップ()
}
ステップ()

async/await を使用すると、同期コードのスタイルで非同期コードを記述できます。async/await ソリューションの方が直感的であることは間違いありませんが、Promise を深く理解することが async/await を習得するための基礎となります。

上記は、Javascript 非同期プログラミングの詳細です。Javascript 非同期プログラミングの詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • js Promise同時制御メソッド
  • JavaScriptはPromiseを使用して複数の繰り返しリクエストを処理します
  • JavaScript で Promise を使用して同時リクエスト数を制御する方法
  • JS 非同期コードユニットテストの魔法 Promise
  • JS 9 Promise 面接の質問
  • JS の Promise に中止関数を追加する方法
  • JS 非同期スタック トレース: await が Promise よりも優れている理由
  • JavaScript PromiseとAsync/Awaitの詳細な説明
  • フロントエンドJavaScriptの約束

<<:  仕事でよく使うLinuxコマンドまとめ

>>:  Linux で JDK 環境を構成する方法

推薦する

VMware vCenter の不正な任意ファイルアップロードの脆弱性 (CVE-2021-21972) について

背景CVE-2021-21972 VMware vCenter における認証されていないコマンド実行...

el-table のテーブルを最適化するために仮想リストを使用する方法についての簡単な説明

目次序文解決具体的な実装満たすべき前提条件質問序文テーブルをよく使用します。データ量が多い場合は直接...

mysql 5.6.21 のインストールと設定の詳細な手順

1. 概要MySQL バージョン: 5.6.21ダウンロードアドレス: https://dev.my...

MySQL データベースの show processlist コマンドの使用の分析

実際のプロジェクト開発では、多数のクエリや挿入、特にマルチスレッド挿入など、データベースに大きな負荷...

MySQLでグローバル変数とセッション変数を設定する2つの方法の詳細な説明

1. MySQL でグローバル変数を変更するには 2 つの方法があります。方法 1: my.ini ...

Vueはカードフリップ効果を実現します

この記事では、カードフリップ効果を実現するためのVueの具体的なコードを例として紹介します。具体的な...

Vue ユニットテストに関する予備調査

目次序文なぜユニットテストを導入するのですか?ユニットテストの概要テスト開発パターン1. テスト駆動...

React Native環境のインストールプロセス

react-native インストールプロセス1.npx react-native init Awe...

Debian ベースの Linux システム ソフトウェア インストール コマンドの詳細な説明 (推奨)

Debian の紹介Debian は、広い意味では、フリーなオペレーティング システムの作成に専念...

Centos7でのMySQLインストールチュートリアル

MySQLインストールチュートリアル、参考までに具体的な内容は次のとおりです。 1. ダウンロードY...

時点別のMySQLデータベース復旧実績

はじめに: 時間ポイントによる MySQL データベースの復旧どの企業にとっても、データは最も価値の...

MySQL クエリの最適化: クエリが遅い原因と解決策

開発に携わっている友人、特に MySQL に関係のある友人は、非常に遅い MySQL クエリに遭遇す...

CentOS 8 に MySql をインストールしてリモート接続を許可する方法

ダウンロードしてインストールします。まず、システムに MySQL または MariaDB があるかど...

MySQLのトランザクションとデータ一貫性処理の問題を分析する

この記事では、セキュリティ、使用方法、同時処理などを通じて、MySQL トランザクションとデータの一...

Angularフレームワークのビュー抽象定義の詳細な説明

序文「大規模なフロントエンド プロジェクト向け」に設計されたフロントエンド フレームワークである A...