質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.09%

【JavaScript】Promiseオブジェクトとdoneとは、一言で言って何ですか?

解決済

回答 5

投稿

  • 評価
  • クリップ 2
  • VIEW 1,607

WeilSpinor

score -34

はじめに

プログラミング初心者です。
JavaScriptの勉強のため、あるアプリのサンプルプログラムのJavaScript(おそらくjQuery)のコードを見ていたら、Promiseというオブジェクトが登場しました。
今回は、Promiseというオブジェクトと、doneというメソッド(?)が、一言で言ってどういう動作をするものなのか知りたくて質問させて頂きました。

 事の経緯

勉強のために参考にしていたアプリというのは、
MonacaというクラウドIDEサービスを利用して作られた『メモ帳アプリ』です。
https://docs.monaca.io/ja/sampleapp/samples/backend_memo/#%E3%83%A1%E3%83%A2%E3%81%AE%E8%BF%BD%E5%8A%A0

メモの内容の保存先として、Monaca Backendという独自のデータベースを利用しており、
そのデータベースのAPI(=独自のオブジェクト群)を利用して、データベース内のメモデータの編集(読み書き)をしたり、新規作成したり、といった操作をする、
という形になっています。

Promiseの登場場面

以下は、上記のメモ帳アプリの解説ページにて、「メモの追加」という項目について、ソースコードを抜粋して解説した記事になります。以下のソースコードの14行目に問題の「done」というメソッド(?)が登場します。

メモの追加 
追加ページ上で Save ボタンを押したときに、onSaveBtn() を呼び出します。次に、ページ上で入力された title と content の値を、 addMemo() 関数に渡します。
この関数では、 monaca.cloud.Collection().insert() ( Monaca バックエンド API ) を使用して、 Memo コレクションに、コレクションアイテムを挿入します。

function onSaveBtn()
{
  var title = $("#title").val();
  var content = $("#content").val();
  if (title != '')
  {
    addMemo(title,content);
  }
}

function addMemo(title,content) {
  var memo = MC.Collection("Memo");

  memo.insert({ title: title, content: content})
  .done(function(insertedItem)
  {
    console.log('Insert is success!');
    $("#title").val("");
    $("#content").val("");
    //display a dialog stating that the inserting is success
    $( "#okDialog_add" ).popup("open", {positionTo: "origin"}).click(function(event)
    {
      event.stopPropagation();
      event.preventDefault();
      getMemoList();
      $.mobile.changePage('#ListPage');
    });
  })
  .fail(function(err){ console.log('Insert failed!');})
}


「done」の一つ手前にある「insert」というAPI独自のオブジェクトの使い方を調べるため、次の解説ページを確認することにしました。https://docs.monaca.io/ja/reference/monaca_api/cloud/collection/#collection-insert
すると、どうやら、この「done」というのは「Promise」というJavaScriptのオブジェクト(というよりjQuery?)のメソッドのようなものだということがわかりました。

Promiseとは?doneとは?

検索にかけてみると、「非同期処理でつかう」「コールバック関数」というフレーズが出てきたのですが、「どういうもので、どういう場面でどんな風に使うものなのか」よくわかりませんでした。(そもそも、コールバック関数を知りません)

Promiseとdoneの解説をしている記事はもちろん色々あるのですが、どの記事も今の私のレベルを超えた予備知識を前提としているような雰囲気で、よくわかりませんでした。

なので、
とりあえず、このプログラムのこの場面に限定して「doneというものがどういう役割を果たしているのか?」を簡潔にご教示頂きたいです。宜しくお願いします。

蛇足~勉強のやり方としてどうなのか~

どうやら、プログラミングというものは、基本のキ的な入門書を読んだ後は、次のステップといったものが特にないらしく、『能動学習的叩き上げ』で勉強していくものらしいので、

突然大海に放り出された気分ですが、
とりあえずアプリを作ってみるか、と考え、やっています。

しかし、そもそも非同期処理やコールバック関数という予備知識も知らないのに、いきなり3歩4歩先の概念であるPromiseというものが出てきてしまうと、さすがに詰まってしまい、勉強効率も落ちます。(1歩2歩さきならいいですが、3歩4歩は飛びすぎで困ります)
「もう少しステップアップ式にできないものなのか…」と思ってしまいました。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kei344

    2019/03/07 02:16

    (質問文は編集できます)タイトルおよび質問文から「一言で言って」を外したほうがよいのでは。(「メソッド」とか言われても困るでしょ)

    キャンセル

  • kei344

    2019/03/07 02:17

    過去の質問について、「解決済」になっていないものが多数見受けられます。解決したものは「ベストアンサー」を選び、自力で解決した場合はその方法を解答欄に書き、もし万が一解決していないのであれば質問を編集するなどしてみてください。

    キャンセル

回答 5

checkベストアンサー

+3

Promiseとは?doneとは?

要は「イベント駆動」の一種だと考えるといいと思います。

JavaScriptも、そのプログラミングコードをひとつひとつ評価して解決していくフロー的な駆動をするのですが、長い待ち時間が発生する場合、それでは都合が悪い場合があります。
たとえば、ブラウザでユーザー入力をさせる代表的な命令はwindow.promptですが、これはユーザーの入力待ちをしている間、画面がロックしてしまいます。

ご質問の場合、メモにテキストを書き込む待ち時間が発生するのでしょう。これをフロー的に解決するとメモ帳の書き込みが終わるまで「アプリが固まる」わけです。
ここで登場するのが「非同期処理」です。

メモ書込を指示→────┐
↓           │
(他の処理をしてる) (メモ書込が終わった)
↓           │
↓           ↓
(他の処理をしてる) メモ書込終了処理

こうすることによって、待ち時間の間に「アプリが固まる」こともなく処理をすることができます。

さて、次にPromiseとはなんであるか、なのですが、これはその「非同期処理」を書きやすくしたものです。
歴史的な背景は「コールバック地獄 Promise」とかでググっていただくとして、処理のイメージとしてはこんな感じです。

メモ書込を指示→─────┐
↓            │
↓←─Promise ─────(はじめたよー)
↓            │
メモ書込終了処理を指示  │
↓    ↓       │
↓   done       │
↓    ↓       │
↓    ↓     (メモ書込が終わった)
↓    ↓       │
↓    ↓←resolve ←(おわったよー)
↓    ↓       
↓    ↓       
↓  メモ書込終了処理
↓           
(他の処理をしてる)

ものすごく大雑把に言うと、
Promiseは、処理指示に対して「終わったら連絡するよ」と返すことで、
doneは、「終わったらこれをやっておいて」と指示することで、
resolveは、「終わったよ」という連絡です。

ご理解いただけましたでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/07 19:48

    ご回答ありがとうございます。参考にさせていただきます

    キャンセル

+3

Promise

 Promiseオブジェクトとdoneとは、一言で言って何ですか?

Promiseはコールバック関数で処理成功(then)、処理失敗(catch)を待つ仕組みです。
azuさんが『Promiseの本』という大変詳しいサイトを立ち上げて下さっていますので、一読を勧めます。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise
http://azu.github.io/promises-book/

コールバック関数

検索にかけてみると、「非同期処理でつかう」「コールバック関数」というフレーズが出てきたのですが、「どういうもので、どういう場面でどんな風に使うものなのか」よくわかりませんでした。(そもそも、コールバック関数を知りません)

分からない単語の概念を調べて下さい。
コールバック関数を理解せずして、Promiseを理解する事は出来ません。
これはこういうものであると一言で説明して、全てを理解する程の天才はそうそういません。
分からない内容をより単純な基礎レベルまで落とし込んで各個撃破する必要があります。
https://www.google.com/search?q=javascript+%e3%82%b3%e3%83%bc%e3%83%ab%e3%83%90%e3%83%83%e3%82%af%e9%96%a2%e6%95%b0

done

Promiseにdoneはありません
jQueryにdoneはありますが、勉強目的なら、jQueryは後回しにすることを勧めます。
https://api.jquery.com/deferred.done/
https://www.google.com/search?q=jquery+defferd

Re: WeilSpinor さん

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/07 23:06 編集

    先ほど、codeprepというサイトに登録しました。ステップアップ式にJavaScriptを学べる素晴らしい学習サイトですが、JavaScriptの基本操作コースとオブジェクト指向の理解コースが終わったら、すぐにjQueryの使い方に移っていました。
    私が以前本で買ったJavaScriptの入門書にしても、最期のほうにjQueryの紹介と練習問題を設けてます。

    結局、JavaScriptを使う以上は、jQueryを使うのが前提というか、セットとして覚えていくしかないのではないでしょうか?
    では、JavaScriptオンリーで実用的レベルのプログラムのコーディングをするにあたって、参照できる文献がない、ということになってしまいます。

    確かに検索すると、昔の趣味ブログみたいなところで、jQueryを使わずに作ったJavaScriptのおもちゃのソースコードは確かに見つかりますが、その程度なんです。正式に勉強したいとなって、こういった少数の非公式なリソースしか教材になりえないなんて、困りませんか?
    プログラミングの世界は、こうした教科書や参考書のようなものは整備されていないのでしょうか?

    キャンセル

  • 2019/03/08 12:58

    論点がずれています。
    @WeilSpinor さんは「jQueryを覚えるべき」といっており、私は「jQueryを覚えるのが早すぎる」といっています。
    三輪車に乗れない人は一輪車にも乗れません。
    「コールバック関数を理解しており、コールバック関数を使った自作コードを書けること」「Promiseの本を理解できること」「非同期処理のコードを書けること」は理解している必要があると考えます。

    茨の道を進みたいのなら止めません。
    親記事にも書いていますが、公式サイト https://api.jquery.com/deferred.done/ にほぼ全てが書かれています。
    足りない部分はjquery.jsを解読すれば、全てが分かります。

    しかし、私は@WeilSpinorさんには早すぎると思います。

    キャンセル

  • 2019/03/09 11:17 編集

    To: 低評価を投じられた方
    低評価の理由を教えて下さい。

    キャンセル

+2

Promiseとdoneの解説をしている記事はもちろん色々あるのですが、どの記事も今の私のレベルを超えた予備知識を前提としているような雰囲気で、よくわかりませんでした。 

本末転倒かもしれませんが、今の理解を超えていると感じたのは実は非常に良いことで、今はまだそこに手を出すべきではないということにもなります。
(ドキュメントや解説サイトを読んで自分でも動かしてみても分からないこともありますが、つまりそういうこと)

ただなんとなくコピペで使ってなんとなくうまいこと動いて、ではすぐに詰まりますので、「予備知識」というところ、きちんとおさえていってはどうでしょうか。
必ず導入しなければいけないかと言うとそこは要件次第なところでもありますし、もう少し簡単なところからステップアップされてはどうでしょうか。
階段は1段1段のぼっていくもので、2段飛ばし3段飛ばしのようなことはすべきではないです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/07 06:03

    本当に一言で、となると既に指摘があるように「メソッド」になりますし、
    英語だとdoの過去分詞、「~された」ですね。
    つまり、doneは「非同期処理"がされた"あとにその処理結果をうけとって次の処理へ・・・」みたいな。イメージです。

    キャンセル

  • 2019/03/09 18:16

    ご回答ありがとうございます。参考にさせていただきます

    キャンセル

+2

しかし、そもそも非同期処理やコールバック関数という予備知識も知らないのに、いきなり3歩4歩先の概念であるPromiseというものが出てきてしまうと、さすがに詰まってしまい、

そういう自覚がしっかりあるのなら、まず、非同期処理やコールバックについて勉強すればいいのでは?
「3,4歩先の概念が出てきてしまい、手も足も出ない」という最悪の状況ではないわけですから。1,2歩目が非同期処理やコールバックだという方向性もあっています。

基本のキ的な入門書を読んだ後は、

それはよい事です。入門書を読むより、コードを読んだり書いたりを薦める人もたまにいますが、それでは間違った知識を得てしまう可能性が高いです。

次のステップといったものが特にないらしく、『能動学習的叩き上げ』で勉強していくものらしいので、 

次としては、公式リファレンスを読む力を付ける事でしょうか。

さらにそこから先は、万人に共通する道はないと思います。
センスがあり、自分で物を考えられる力がある人は、書いてみて、うまくいかないところや、分からない所を調べるという方法で良いと思いますが、
考える力が弱い人が書き始めると、泥沼にはまって、こういうサイトで、訳の分からない質問をする事になります。そういう人は、まず読んで完全に理解するところから始めるのがいい気がします。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/07 19:53

    ご回答ありがとうございます。

    ある人曰く、
    「プログラミングができる」とは「自分のやりたいことを実現できる」ということらしく、
    そのための学習の方法は、結局のところ、
    「何かを作りながら覚える」以外にないらしいので、
    そのためにアプリを作ろうと思い、自分が使いたいモジュールを備えた単純なアプリのソースコードを読んで勉強している、という感じです。

    『【プログラミング入門者必見】スマホアプリ開発でよく使われる実用モジュールを通してJavaScriptの概念・イディオムを学ぶサンプルプログラム集【例題と演習】』のような本をやった方がよいのでしょうか?

    もちろん、できることならば、初心者の私としては
    promiseなどというコマンドを使わずに、(できればjQueryも使わずに)、
    もっと基本的な概念を使って組み立てることができれば、と思うのですが、
    しかし、「プログラミングをする」ことと「アプリを制作する」という営みの間には開きがあるようで、
    アプリを作る、というレベルの話になると、
    かたくなに生のJavaScriptのコードのみで作っているものはあまりないようで、
    ふつうはjQueryのようなライブラリだったり、各種APIの力を借りながら実装しているソースコードにしか出会えません。


    これは私どもの経験になりますが、(生意気なことを言ってしまい、大変恐縮です)
    勉強にしろ芸事にしろ、
    一個一個ステップが用意されている、という理想的なやり方をいつでもできるわけではなく、
    「時々階段が途切れていて、そこは1,2段ジャンプしなければならない」
    「とりあえず与えられた文脈における限定された意味合いだけ理解して、基礎的な話は後回しにする」
    という『アクロバティックな勉強法』がどうしても必要な場面というのが、往々にしてあるみたいです。
    (私の恩師いわく、「わかったふりをする能力が重要な場合がある」そうです)


    このアプリのコードに関しては、
    doneの部分を除けば、おおむね理解できるように思うので、とりあえずちゃんとした意味は「ブラックボックス」として、ゴリゴリ進めたほうがよいのかな?、とも思いました。

    なかなか難しい問題ですね…

    「困難は分割して考える」というデカルトの言葉に従い、
    一応コールバックや非同期処理についても独立に調べてみたのですが、今回はうまくいかなかったみたいです…。

    場合によっては、
    「まずは小さな要素に分けて理解」→「あとでそれらを組み合わせる」
    というやり方よりも、

    「塊を場面に応じたイディオム=「型」として覚えこんでしまう」
    →「基礎的なお話、理論的なことは、慣れた後に改めて教科書などを読んで、あとからじんわりと理解していく」
    というやり方が良いこともあるようで、
    そのやり方で試している、という感じです。

    しかし、こういったやり方は、指導者がいてこそなりたつもので、
    独学でやるには難しいのかもしれません…。

    少しずれたお話をしてしまい、申し訳ありません。

    キャンセル

  • 2019/03/07 21:51

    万人に共通する道はないと書いたとおりだと思います。

    > (私の恩師いわく、「わかったふりをする能力が重要な場合がある」そうです)
    このアドバイスは非常に良いと思います。
    ただ、人によっては、それっきり分からないままの人もいれば、何度か経験しているうちに、自分の頭で考えて、本当に分かる人もいるでしょう。

    私からのアドバイスとしては、「分かった振りをしているが、本当には分かっていない物リスト」を作っておくことでしょうか。で、それを消し込んでいければ良い。

    貴方の場合は、文章を読んでいる限りでは、大丈夫な気がしますが、そうじゃなくて、自分の頭で考える力の弱い人の場合、設計できるプログラマになるためには、どうしたら良いのか正直分かりません。猫の手プログラマには十分なれると思うのですが。

    自分の頭で考える力のある人の場合、別のアプローチとしては、低階層のことをしっかり理解していれば、上位階層のことは、大抵のことなら見て考えればだいたい分かるという方法もあります。
    低階層=CPUの動く仕組み、OSの基本動作、言語処理系の仕組みなど。

    キャンセル

  • 2019/03/08 02:40

    なるほど、
    私自身、理論物理を勉強してきた人間、ということがあってか、
    プログラミングを勉強していると低階層のことが気になってしまう性分です。(だからこういう質問を立ててしまう)
    コンピューターのすべてを包括的に理解するという目的の場合は、
    むしろそういうボトムアップ式に勉強するのもありかもしれません。

    しかし、今勉強しているのは、アプリ開発であったりして、
    なかなか低階層の処理は見えないようにしていて、むしろ、
    「様々なパッケージの使い方を知っているかいないか」
    ということが重要な気がするので、なかなか辛いものです…。

    「分かったふりをしてスルーしたものリスト」を早速つくりました。
    そんな感じでやっていこうと思います。

    その公式リファレンスというものも、書店などで
    見てみようと思います。

    キャンセル

  • 2019/03/08 09:47

    > その公式リファレンスというものも、書店などで
    いや、今時は、変化が早いので、書籍にはなってないのが普通です。
    JavaScriptならMozillaのサイト、Python PHP Ruby Java等もそれぞれサイトがあります。
    https://developer.mozilla.org/ja/docs/Web/JavaScript

    キャンセル

0

おそらく、insertによってデータベースへの書き込みが成功したらdoneが呼ばれるということだと思います。
プログラム言語によって様々な設計思想がありますが、同期処理に着目すると、例えばjavascriptではデータベースへの書き込みの成功失敗を問わず、次の処理を行ってしまうのに対し、rubyは成功失敗の結果を待ってから次の処理に移ります。
プログラムでは、javascriptではdoneやfailの中にあるcallbackによってデータベースの結果を使った処理を予約しているのに対し、rubyではresult=addmemo(title, content)で結果を受け取り、その下にif result==true〜と処理を書くといったことをします。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/09 18:15

    ご回答ありがとうございます。rubyという言語は非同期処理が考えがjavascript に比べて希薄な言語なんですかね?参考にさせていただきます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.09%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる