1. ホーム
  2. javascript

[解決済み] プロミスは単なるコールバックではないのか?

2022-03-20 02:23:15

質問

数年前からJavaScriptを開発していますが、プロミスについての騒動が全く理解できません。

変更ばかりしているような気がします。

api(function(result){
    api2(function(result2){
        api3(function(result3){
             // do work
        });
    });
});

のようなライブラリを使用することができます。 非同期 のようなもので、とにかく

api().then(function(result){
     api2().then(function(result2){
          api3().then(function(result3){
               // do work
          });
     });
});

どちらがコード量が多く、可読性に劣るでしょうか。ここでは何も得られなかったし、突然魔法のように「フラット」になったわけでもない。もちろん、プロミスに変換しなければならないのは言うまでもありません。

では、ここでプロミスについて大騒ぎしているのは何なのか?

どのように解決するのか?

プロミスはコールバックではありません。プロミスは 非同期操作の将来の結果 . もちろん、そのような書き方をしていても、ほとんどメリットはありません。しかし、本来の使い方をすれば、非同期コードを同期コードに似た形で書くことができ、より簡単に従うことができます。

api().then(function(result){
    return api2();
}).then(function(result2){
    return api3();
}).then(function(result3){
     // do work
});

確かに、コードはあまり減りませんが、読みやすさは格段に向上しています。

しかし、これで終わりではありません。本当の効果を発見してみましょう。もし、ステップのどれかにエラーがないかチェックしたいとしたらどうでしょう?コールバックでそれを行うのは大変ですが、プロミスを使えば楽勝です。

api().then(function(result){
    return api2();
}).then(function(result2){
    return api3();
}).then(function(result3){
     // do work
}).catch(function(error) {
     //handle any error that may occur before this point
});

とほぼ同じです。 try { ... } catch ブロックを作成します。

もっといいのは

api().then(function(result){
    return api2();
}).then(function(result2){
    return api3();
}).then(function(result3){
     // do work
}).catch(function(error) {
     //handle any error that may occur before this point
}).then(function() {
     //do something whether there was an error or not
     //like hiding an spinner if you were performing an AJAX request.
});

そして、さらに良いことがあります。もし、これらの3つの呼び出しを api , api2 , api3 は同時に実行できましたが (たとえば AJAX 呼び出しの場合)、3 つの待ち時間が必要だったのでしょうか。プロミスがなければ、ある種のカウンターを作らなければならないはずです。約束があれば、ES6記法を使用して、別のケーキの部分とかなりきれいです。

Promise.all([api(), api2(), api3()]).then(function(result) {
    //do work. result is an array contains the values of the three fulfilled promises.
}).catch(function(error) {
    //handle the error. At least one of the promises rejected.
});

プロミスを新しい視点で見ていただけると幸いです。