ES6でのPromiseの使い方を詳しく解説
今回はES6でPromiseを使う際の注意点について詳しく解説していきます。
もちろん、これは爆発的にフルスタックになったという意味ではありません。スタック全体のスキルは非常に集中しており、フロントエンドが HTML と対話を作成できるだけでなく、バックエンドもデータベースの追加、削除、チェック、変更に精通しています。
Node に関わったことがある人なら誰でも、Node は非同期 (Async) コールバックで有名であることを知っているはずです。その非同期性により、プログラムの実行効率が向上しますが、プログラムの可読性も低下します。複数の非同期操作があり、後の操作では前の操作によって返されたデータを実行する必要がある場合、Node の一般的な実行ルールに従って、通常、順序付けられた非同期操作はレイヤーごとにネストされます。
この問題を解決するために、ES6 は Promise の実装を提案しました。
意味
Promise Object は、非同期操作の最終的な完了 (または失敗) とその結果値を表すために使用されます。簡単に言うと、非同期処理が成功した場合は、成功した処理が実行され、非同期処理が失敗した場合は、エラーが捕捉されるか、以降の処理が停止されます。
その一般的な表現は次のとおりです:
new Promise( /* executor */ function(resolve, reject) { if (/* success */) { // ...执行代码 resolve(); } else { /* fail */ // ...执行代码 reject(); } } );
このうち、Promise のパラメータ executor は、resolve と accept の 2 つのパラメータを持つ executor 関数です。通常、内部にはいくつかの非同期操作が含まれています。非同期操作が成功した場合は、resolve() を呼び出してインスタンスの ステータス を設定できます。失敗した場合は、reject() を呼び出します。インスタンスの
ステータスをフルフィルメントに設定します。ステータスは拒否、つまり失敗に設定されます。
- Promise オブジェクトは工場の組立ラインと考えることができます。組立ラインのジョブ機能から判断すると、そのジョブの状態は 3 つだけあり、1 つは初期状態 (電源が入ったばかりのとき) で、もう 1 つは初期状態です。 1 つは製品の処理が成功した場合、1 つは製品の処理が失敗した場合 (何らかの障害が発生した場合) です。同様に、Promise オブジェクトにも 3 つの状態があります:
- pending: 初期状態 (未決定状態とも呼ばれます) は、Promise の初期化時に executor executor 関数を呼び出した後の状態です。
- fulfilled: 完了ステータス。非同期操作が成功したことを意味します。
- rejected: 失敗ステータス。非同期操作が失敗したことを意味します。
- 変換できる状態は 2 つだけです。つまり、
- 操作が成功しました: 保留中 -> 完了
- 操作が失敗しました: 保留中 -> 拒否されました
とこの状態変換これは一方向で不可逆的であり、決定された状態 (履行/拒否) を初期状態 (保留中) に戻すことはできません。 method
Promise.prototype.then()
Promise オブジェクトには then() が呼び出された後、Promise オブジェクトが返されます。つまり、インスタンス化された Promise オブジェクトはそして、この then() メソッドは 2 つの関数を受け取ることができます。1 つは処理が成功した後の関数で、もう 1 つはエラー結果を処理する関数です。
以下の通り:
var promise1 = new Promise(function(resolve, reject) { // 2秒后置为接收状态 setTimeout(function() { resolve('success'); }, 2000); }); promise1.then(function(data) { console.log(data); // success }, function(err) { console.log(err); // 不执行 }).then(function(data) { // 上一步的then()方法没有返回值 console.log('链式调用:' + data); // 链式调用:undefined }).then(function(data) { // .... });
ここでは主に、promise1.then() メソッドが呼び出された後に返される Promise オブジェクトのステータスに焦点を当てます。保留中、履行済み、または拒否済みですか?
- 返される Promise オブジェクトのステータスは次のとおりです。主にpromise1をベースにしていますが、then()メソッドで返される値は以下の場合に大別されます。
- then()メソッドでパラメータ値が返された場合、返されたPromiseが受信状態になります。
- then() メソッドで例外がスローされた場合、返された Promise は拒否されます。
- then()メソッドがresolve()メソッドを呼び出すと、返されたPromiseが受信状態になります。
- then() メソッドが拒否() メソッドを呼び出すと、返された Promise は拒否されます。
- then() メソッドが不明な状態 (保留中) の新しい Promise インスタンスを返した場合、返された新しい Promise は不明な状態になります。
- then() メソッドで、resolve(data)/reject(data)/return data が明示的に指定されていない場合、返される新しい Promise は受信状態であり、レイヤーごとに受け渡すことができます。
var promise2 = new Promise(function(resolve, reject) { // 2秒后置为接收状态 setTimeout(function() { resolve('success'); }, 2000); }); promise2 .then(function(data) { // 上一个then()调用了resolve,置为fulfilled态 console.log('第一个then'); console.log(data); return '2'; }) .then(function(data) { // 此时这里的状态也是fulfilled, 因为上一步返回了2 console.log('第二个then'); console.log(data); // 2 return new Promise(function(resolve, reject) { reject('把状态置为rejected error'); // 返回一个rejected的Promise实例 }); }, function(err) { // error }) .then(function(data) { /* 这里不运行 */ console.log('第三个then'); console.log(data); // .... }, function(err) { // error回调 // 此时这里的状态也是fulfilled, 因为上一步使用了reject()来返回值 console.log('出错:' + err); // 出错:把状态置为rejected error }) .then(function(data) { // 没有明确指定返回值,默认返回fulfilled console.log('这里是fulfilled态'); });
Promise.prototype.catch()
catch()方法和then()方法一样,都会返回一个新的Promise对象,它主要用于捕获异步操作时出现的异常。因此,我们通常省略then()方法的第二个参数,把错误处理控制权转交给其后面的catch()函数,如下:
var promise3 = new Promise(function(resolve, reject) { setTimeout(function() { reject('reject'); }, 2000); }); promise3.then(function(data) { console.log('这里是fulfilled状态'); // 这里不会触发 // ... }).catch(function(err) { // 最后的catch()方法可以捕获在这一条Promise链上的异常 console.log('出错:' + err); // 出错:reject });
Promise.all()
Promise.all()接收一个参数,它必须是可以迭代的,比如数组。
它通常用来处理一些并发的异步操作,即它们的结果互不干扰,但是又需要异步执行。它最终只有两种状态:成功或者失败。
它的状态受参数内各个值的状态影响,即里面状态全部为fulfilled时,它才会变成fulfilled,否则变成rejected。
成功调用后返回一个数组,数组的值是有序的,即按照传入参数的数组的值操作后返回的结果。如下:
// 置为fulfilled状态的情况 var arr = [1, 2, 3]; var promises = arr.map(function(e) { return new Promise(function(resolve, reject) { resolve(e * 5); }); }); Promise.all(promises).then(function(data) { // 有序输出 console.log(data); // [5, 10, 15] console.log(arr); // [1, 2, 3] });
// 置为rejected状态的情况 var arr = [1, 2, 3]; var promises2 = arr.map(function(e) { return new Promise(function(resolve, reject) { if (e === 3) { reject('rejected'); } resolve(e * 5); }); }); Promise.all(promises2).then(function(data) { // 这里不会执行 console.log(data); console.log(arr); }).catch(function(err) { console.log(err); // rejected });
Promise.race()
Promise.race()和Promise.all()类似,都接收一个可以迭代的参数,但是不同之处是Promise.race()的状态变化不是全部受参数内的状态影响,一旦参数内有一个值的状态发生的改变,那么该Promise的状态就是改变的状态。就跟race单词的字面意思一样,谁跑的快谁赢。如下:
var p1 = new Promise(function(resolve, reject) { setTimeout(resolve, 300, 'p1 doned'); }); var p2 = new Promise(function(resolve, reject) { setTimeout(resolve, 50, 'p2 doned'); }); var p3 = new Promise(function(resolve, reject) { setTimeout(reject, 100, 'p3 rejected'); }); Promise.race([p1, p2, p3]).then(function(data) { // 显然p2更快,所以状态变成了fulfilled // 如果p3更快,那么状态就会变成rejected console.log(data); // p2 doned }).catch(function(err) { console.log(err); // 不执行 });
Promise.resolve()
Promise.resolve()接受一个参数值,可以是普通的值,具有then()方法的对象和Promise实例。正常情况下,它返回一个Promise对象,状态为fulfilled。但是,当解析时发生错误时,返回的Promise对象将会置为rejected态。如下:
// 参数为普通值 var p4 = Promise.resolve(5); p4.then(function(data) { console.log(data); // 5 }); // 参数为含有then()方法的对象 var obj = { then: function() { console.log('obj 里面的then()方法'); } }; var p5 = Promise.resolve(obj); p5.then(function(data) { // 这里的值时obj方法里面返回的值 console.log(data); // obj 里面的then()方法 }); // 参数为Promise实例 var p6 = Promise.resolve(7); var p7 = Promise.resolve(p6); p7.then(function(data) { // 这里的值时Promise实例返回的值 console.log(data); // 7 }); // 参数为Promise实例,但参数是rejected态 var p8 = Promise.reject(8); var p9 = Promise.resolve(p8); p9.then(function(data) { // 这里的值时Promise实例返回的值 console.log('fulfilled:'+ data); // 不执行 }).catch(function(err) { console.log('rejected:' + err); // rejected: 8 });
Promise.reject()
Promise.reject()和Promise.resolve()正好相反,它接收一个参数值reason,即发生异常的原因。此时返回的Promise对象将会置为rejected态。如下:
var p10 = Promise.reject('手动拒绝'); p10.then(function(data) { console.log(data); // 这里不会执行,因为是rejected态 }).catch(function(err) { console.log(err); // 手动拒绝 }).then(function(data) { // 不受上一级影响 console.log('状态:fulfilled'); // 状态:fulfilled });
总之,除非Promise.then()方法内部抛出异常或者是明确置为rejected态,否则它返回的Promise的状态都是fulfilled态,即完成态,并且它的状态不受它的上一级的状态的影响。
总结
大概常用的方法就写那么多,剩下的看自己实际需要再去了解。
解决Node回调地狱的不止有Promise,还有Generator和ES7提出的Async实现。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
以上がES6でのPromiseの使い方を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









CrystalDiskMark は、シーケンシャルおよびランダムの読み取り/書き込み速度を迅速に測定する、ハード ドライブ用の小型 HDD ベンチマーク ツールです。次に、編集者が CrystalDiskMark と Crystaldiskmark の使用方法を紹介します。 1. CrystalDiskMark の概要 CrystalDiskMark は、機械式ハード ドライブとソリッド ステート ドライブ (SSD) の読み取りおよび書き込み速度とパフォーマンスを評価するために広く使用されているディスク パフォーマンス テスト ツールです。 ). ランダム I/O パフォーマンス。これは無料の Windows アプリケーションで、使いやすいインターフェイスとハード ドライブのパフォーマンスのさまざまな側面を評価するためのさまざまなテスト モードを提供し、ハードウェアのレビューで広く使用されています。

foobar2000 は、音楽リソースをいつでも聴くことができるソフトウェアです。あらゆる種類の音楽をロスレス音質で提供します。音楽プレーヤーの強化版により、より包括的で快適な音楽体験を得ることができます。その設計コンセプトは、高度なオーディオをコンピュータ上で再生可能 デバイスを携帯電話に移植し、より便利で効率的な音楽再生体験を提供 シンプルでわかりやすく、使いやすいインターフェースデザイン 過度な装飾や煩雑な操作を排除したミニマルなデザインスタイルを採用また、さまざまなスキンとテーマをサポートし、自分の好みに合わせて設定をカスタマイズし、複数のオーディオ形式の再生をサポートする専用の音楽プレーヤーを作成します。過度の音量による聴覚障害を避けるために、自分の聴覚の状態に合わせて調整してください。次は私がお手伝いさせてください

NetEase Mailbox は、中国のネットユーザーに広く使用されている電子メール アドレスとして、その安定した効率的なサービスで常にユーザーの信頼を獲得してきました。 NetEase Mailbox Master は、携帯電話ユーザー向けに特別に作成された電子メール ソフトウェアで、電子メールの送受信プロセスが大幅に簡素化され、電子メールの処理がより便利になります。 NetEase Mailbox Master の使い方と具体的な機能について、以下ではこのサイトの編集者が詳しく紹介しますので、お役に立てれば幸いです。まず、モバイル アプリ ストアで NetEase Mailbox Master アプリを検索してダウンロードします。 App Store または Baidu Mobile Assistant で「NetEase Mailbox Master」を検索し、画面の指示に従ってインストールします。ダウンロードとインストールが完了したら、NetEase の電子メール アカウントを開いてログインします。ログイン インターフェイスは次のとおりです。

クラウド ストレージは今日、私たちの日常生活や仕事に欠かせない部分になっています。中国有数のクラウド ストレージ サービスの 1 つである Baidu Netdisk は、強力なストレージ機能、効率的な伝送速度、便利な操作体験により多くのユーザーの支持を得ています。また、重要なファイルのバックアップ、情報の共有、オンラインでのビデオの視聴、または音楽の聴きたい場合でも、Baidu Cloud Disk はニーズを満たすことができます。しかし、Baidu Netdisk アプリの具体的な使用方法を理解していないユーザーも多いため、このチュートリアルでは Baidu Netdisk アプリの使用方法を詳しく紹介します。まだ混乱しているユーザーは、この記事に従って詳細を学ぶことができます。 Baidu Cloud Network Disk の使用方法: 1. インストール まず、Baidu Cloud ソフトウェアをダウンロードしてインストールするときに、カスタム インストール オプションを選択してください。

MetaMask (中国語ではリトル フォックス ウォレットとも呼ばれます) は、無料で評判の高い暗号化ウォレット ソフトウェアです。現在、BTCC は MetaMask ウォレットへのバインドをサポートしており、バインド後は MetaMask ウォレットを使用してすぐにログイン、値の保存、コインの購入などが可能になり、初回バインドで 20 USDT のトライアル ボーナスも獲得できます。 BTCCMetaMask ウォレットのチュートリアルでは、MetaMask の登録方法と使用方法、および BTCC で Little Fox ウォレットをバインドして使用する方法を詳しく紹介します。メタマスクウォレットとは何ですか? 3,000 万人を超えるユーザーを抱える MetaMask Little Fox ウォレットは、現在最も人気のある暗号通貨ウォレットの 1 つです。無料で使用でき、拡張機能としてネットワーク上にインストールできます。

Windows オペレーティング システムは世界で最も人気のあるオペレーティング システムの 1 つであり、その新バージョン Win11 が大きな注目を集めています。 Win11 システムでは、管理者権限の取得は重要な操作であり、管理者権限を取得すると、ユーザーはシステム上でより多くの操作や設定を実行できるようになります。この記事では、Win11システムで管理者権限を取得する方法と、権限を効果的に管理する方法を詳しく紹介します。 Win11 システムでは、管理者権限はローカル管理者とドメイン管理者の 2 種類に分かれています。ローカル管理者はローカル コンピュータに対する完全な管理権限を持っています

OracleSQL の除算演算の詳細な説明 OracleSQL では、除算演算は一般的かつ重要な数学演算であり、2 つの数値を除算した結果を計算するために使用されます。除算はデータベース問合せでよく使用されるため、OracleSQL での除算演算とその使用法を理解することは、データベース開発者にとって重要なスキルの 1 つです。この記事では、OracleSQL の除算演算に関する関連知識を詳細に説明し、読者の参考となる具体的なコード例を示します。 1. OracleSQL での除算演算

Appleは火曜日にiOS 17.4アップデートを公開し、iPhoneに多数の新機能と修正をもたらした。このアップデートには新しい絵文字が含まれており、EU ユーザーは他のアプリ ストアから絵文字をダウンロードすることもできます。さらに、このアップデートでは iPhone のセキュリティ制御も強化され、より多くの「盗難デバイス保護」設定オプションが導入され、ユーザーにより多くの選択肢と保護が提供されます。 「iOS17.3では、「盗難デバイス保護」機能が初めて導入され、ユーザーの機密情報のセキュリティが強化されています。ユーザーが自宅やその他の身近な場所から離れている場合、この機能ではユーザーは最初に生体認証情報を入力する必要がありますApple ID パスワードの変更や盗難デバイス保護の無効化など、特定のデータにアクセスして変更するには、情報を再度入力する必要があります。
