ホームページ > ウェブフロントエンド > jsチュートリアル > 落とし穴をすぐに避け、Promise を使用する際によくある 5 つの間違いについて説明します。

落とし穴をすぐに避け、Promise を使用する際によくある 5 つの間違いについて説明します。

青灯夜游
リリース: 2021-12-08 10:22:19
転載
1895 人が閲覧しました

この記事では、落とし穴をすぐに回避できるように、Promise を使用するときによくある 5 つの間違いを紹介します。

落とし穴をすぐに避け、Promise を使用する際によくある 5 つの間違いについて説明します。

#Promise は、JS で非同期操作を処理するエレガントな方法を提供します。これは「コールバック地獄」を回避するための解決策でもあります。ただし、その内容を理解している開発者はそれほど多くありません。そのため、練習ではミスをしてしまう人が多いです。 [関連する推奨事項: JavaScript 学習チュートリアル #]

この記事では、Promise を使用する際によくある 5 つの間違いを紹介し、誰もがこれらの間違いを回避できることを願っています。

1. Promise 地獄の回避#​​

##通常、Promise はコールバック 地獄を回避するために使用されます。しかし、それらを乱用すると、プロミスが地獄になる可能性もあります。

userLogin('user').then(function(user){
    getArticle(user).then(function(articles){
        showArticle(articles).then(function(){
            //Your code goes here...
        });
    });
});
ログイン後にコピー

上の例では、

userLogingetararticleshowararticle の 3 つのネストされた Promise があります。このようにすると、コードの行数に比例して複雑さが増し、読めなくなる可能性があります。

これを回避するには、コードのネストを解除し、最初の

then から getArticle を返し、次に 2 番目の then で処理する必要があります。それ。

userLogin('user')
  .then(getArticle)
  .then(showArticle)
  .then(function(){
       //Your code goes here...
});
ログイン後にコピー

2. Promise # で try/catch<span style="font-size: 18px;"></span> block を使用します##通常、エラーを処理するには

try/catch

ブロックを使用します。ただし、Promise オブジェクト内で try/catch を使用することはお勧めできません。 これは、エラーが発生した場合、Promise オブジェクトが

catch

内で自動的に処理されるためです。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">ew Promise((resolve, reject) =&gt; { try { const data = doThis(); // do something resolve(); } catch (e) { reject(e); } }) .then(data =&gt; console.log(data)) .catch(error =&gt; console.log(error));</pre><div class="contentsignin">ログイン後にコピー</div></div>上の例では、Promise 内で

try/catch

ブロックを使用しました。 ただし、Promise 自体は、

try/catch

ブロックを必要とせずに、スコープ内のすべてのエラー (タイプミスも含む) をキャッチします。これにより、実行中にスローされたすべての例外が確実にキャッチされ、拒否された Promise に変換されます。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">new Promise((resolve, reject) =&gt; { const data = doThis(); // do something resolve() }) .then(data =&gt; console.log(data)) .catch(error =&gt; console.log(error));</pre><div class="contentsignin">ログイン後にコピー</div></div>

注:

Promise ブロック内で .catch() ブロックを使用することが重要です。そうしないと、テスト ケースが失敗し、本番フェーズ中にアプリケーションがクラッシュする可能性があります。

3. Promise ブロック内で非同期関数を使用する

Async/Await

はより高度な構文であり、処理に使用されます。同期コード内の複数の Promise。関数宣言の前に async キーワードを使用すると、Promise が返されます。await キーワードを使用すると、待機している Promise が解決または拒否されるまでコードを停止できます。 . .

ただし、Async 関数を Promise ブロック内に配置すると、いくつかの副作用が発生します。

Promise ブロックで非同期操作を実行したいので、

async

キーワードを使用しますが、残念ながらコードがエラーをスローするとします。 このように、

catch()

ブロックを使用したり、try/catch ブロック内で Promise を待機したりしても、エラーをすぐに処理することはできません。以下の例を参照してください。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">// 此代码无法处理错误 new Promise(async () =&gt; { throw new Error(&amp;#39;message&amp;#39;); }).catch(e =&gt; console.log(e.message)); (async () =&gt; { try { await new Promise(async () =&gt; { throw new Error(&amp;#39;message&amp;#39;); }); } catch (e) { console.log(e.message); } })();</pre><div class="contentsignin">ログイン後にコピー</div></div>Promise ブロック内で

async

関数に遭遇した場合、同期を保つために async ロジックを Promise ブロックの外に保持しようとします。 10回中9回は機能します。 ただし、場合によっては、

async

関数が必要になる場合があります。この場合は、try/catch ブロックを使用して手動で管理するしかありません。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">new Promise(async (resolve, reject) =&gt; { try { throw new Error(&amp;#39;message&amp;#39;); } catch (error) { reject(error); } }).catch(e =&gt; console.log(e.message)); //using async/await (async () =&gt; { try { await new Promise(async (resolve, reject) =&gt; { try { throw new Error(&amp;#39;message&amp;#39;); } catch (error) { reject(error); } }); } catch (e) { console.log(e.message); } })();</pre><div class="contentsignin">ログイン後にコピー</div></div>

4. Promise を作成した直後に Promise ブロックを実行します次のコード スニペットのように、コード スニペットをHTTP 呼び出しが要求されると、すぐに実行されます。

const myPromise = new Promise(resolve => {
  // code to make HTTP request
  resolve(result);
});
ログイン後にコピー

その理由は、このコードが Promise コンストラクターでラップされているためです。ただし、

myPromise

then メソッドが実行された後にのみトリガーされると考える人もいるかもしれません。

しかし、真実はそうではありません。対照的に、Promise が作成されると、コールバックはすぐに実行されます。

これは、

myPromise

の確立後に次の行に到達するまでに、HTTP リクエストがすでに実行されているか、少なくともスケジュールされた状態になっている可能性が高いことを意味します。

Promise は常にプロセスを実行することに熱心です。

しかし、将来約束を実行したい場合はどうすればよいでしょうか?今すぐ HTTP リクエストを実行したくない場合はどうすればよいですか?これを可能にする魔法のメカニズムが Promise に組み込まれているのでしょうか?

答えは関数を使用することです。関数は時間のかかるメカニズムです。これらは、開発者が

()

を使用して明示的に呼び出した場合にのみ実行されます。関数を定義するだけでは何も進みません。したがって、Promise を遅延させる最も効率的な方法は、Promise を関数でラップすることです!<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">const createMyPromise = () =&gt; new Promise(resolve =&gt; { // HTTP request resolve(result); });</pre><div class="contentsignin">ログイン後にコピー</div></div><p>对于HTTP请求,Promise 构造函数和回调函数只有在函数被执行时才会被调用。所以现在我们有一个懒惰的Promise,只有在我们需要的时候才会执行。</p><p><strong><span style="font-size: 18px;">5. 不一定使用 Promise.all() 方法</span></strong></p><p>如果你已经工作多年,应该已经知道我在说什么了。如果有许多彼此不相关的 Promise,我们可以同时处理它们。</p><p>Promise 是并发的,但如你一个一个地等待它们,会太费时间,<code>Promise.all()可以节省很多时间。

记住,Promise.all() 是我们的朋友
const { promisify } = require(&#39;util&#39;);
const sleep = promisify(setTimeout);

async function f1() {
  await sleep(1000);
}

async function f2() {
  await sleep(2000);
}

async function f3() {
  await sleep(3000);
}


(async () => {
  console.time(&#39;sequential&#39;);
  await f1();
  await f2();
  await f3();
  console.timeEnd(&#39;sequential&#39;);  
})();
ログイン後にコピー

上述代码的执行时间约为 6 秒。但如果我们用 Promise.all() 代替它,将减少执行时间。

(async () => {
    console.time(&#39;concurrent&#39;);
    await Promise.all([f1(), f2(), f3()]);
    console.timeEnd(&#39;concurrent&#39;); 
  })();
ログイン後にコピー

总结

在这篇文章中,我们讨论了使用 Promise 时常犯的五个错误。然而,可能还有很多简单的问题需要仔细解决。

如果你还有更多相关的错误,欢迎留言一起讨论。

英文原文地址:https://blog.bitsrc.io/5-common-mistakes-in-using-promises-bfcc4d62657f

作者:Ravidu Perera

更多编程相关知识,请访问:编程入门!!

以上が落とし穴をすぐに避け、Promise を使用する際によくある 5 つの間違いについて説明します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:segmentfault.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート