1688


jqXHR や Promise が成功した場合に呼ばれる `done(fn)` の fn に渡される引数を、事前に変形できるでしょうか？

次のようなイメージです。

[code]

    $.ajax(...)
        .???(function(originalResult) {
          // originalResult を変形して return
          return someTransform(originalResult);
        }).done(function(result) {
          // result には someTransform(originalResult) が渡される。
        });
    
[/code]


CC BY-SA 3.0
2014-12-16T05:40:08.667
1678
2016-03-18T14:47:41.007
2016-03-18T14:47:41.007
4788
455
question
javascript jquery promise
jQuery の jqXHR や Promise で成功の場合の結果を変形するには？


ちょっと求められているのとは異なりますが、 以下のように wrapTransform() 関数を定義して、 done
で呼び出すべき関数、をwrapTransform()の引数としてしまうという方法はどうでしょうか。

[code]

    function wrapTransform(fn) {
      return function (originalResult) {
        return fn(someTransform(originalResult));
      }
    }
    
    
    $.ajax(...)
      .done(wrapTransform(function(result) {
        // result には someTransform(originalResult) が渡される。
      }));
    
[/code]


CC BY-SA 3.0
2014-12-16T06:06:54.123
1686
2014-12-16T06:06:54.123
208
1678
answer


[`then`](http://api.jquery.com/deferred.then/) がある:

[code]

    $.get("/")
    .then(function(originalResult){
        return "OK";
    })
    .done(function(result){
        //result === "OK"
    });
    
[/code]


CC BY-SA 3.0
2014-12-16T06:12:15.987
1688
2014-12-16T06:12:15.987
3406
1678
answer


Promiseといえば、`.then()`がPromiseのもっとも重要なメソッドで、まさにkawtyさんが求めているものです。

`.then()`メソッドは関数を受け取り、その関数が返す値を代表するPromiseを返します。例えば、

[code]

    var d = $.Deferred();
    
    d.promise().then(function (v) {
      snippet.log(v);                //　9
      return v * 2;
    }).then(function (v2) {
      snippet.log(v2);               // 18
      return v2 + 7;
    }).then(function (v3) {
      snippet.log(v3);               // 25
    });
    
    d.resolve(9);
[/code]

[code]

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
    <script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
[/code]

それだけではなくて、例え`.then()`へ渡す関数から別のPromiseを返しても、そのPromiseの中の値がちゃんと次の`.then()`に渡されます

[code]

    var d = $.Deferred();
    
    d.promise().then(function (v) {
      snippet.log(v);
      return v * 2;
    }).then(function (v2) {
      snippet.log(v2);
    
      var d2 = $.Deferred();
      d2.resolve(v2 + 7);
      return d2.promise();
    }).then(function (v3) {
      snippet.log(v3);
    });
    
    d.resolve(9);
[/code]

[code]

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
    <script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
[/code]

* * *

ちなみに、このようなコードを書く必要はありません。

[code]

    $.ajax(...)
    .then(function(originalResult) {
      return someTransform(originalResult);
    }).done(function(result) {
      // result には someTransform(originalResult) が渡される。
    });
    
[/code]

`.then()`に渡されている匿名関数はただ`originalResult`をそのまま`someTransform()`に渡しているので、この場合は`someTransform`を直接`.then()`に渡すことができるし、この方が読みやすいと思われることが多いです。

[code]

    $.ajax(...)
    .then(someTransform)
    .done(function(result) {
      // result には someTransform(originalResult) が渡される。
    });
    
[/code]

そして最後に、jQueryのPromiseにはいくつかの問題点があり、[あまり使わない方がいい](https://gist.github.com/domenic/3889970)という人が多いです。jqXHRを扱っている場合、早く別のPromiseライブラリ又はJS6の`.when()`メソッドに渡して、ちゃんとしたPromiseに変換した方がいいです。


CC BY-SA 3.0
2014-12-18T12:55:01.147
2042
2015-03-12T07:35:16.457
2015-03-12T07:35:16.457
4788
4788
1678
answer