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

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

新規登録して質問してみよう
ただいま回答率
85.51%
ECMAScript

ECMAScriptとは、JavaScript類の標準を定めるために作られたスクリプト言語です。

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

2645閲覧

引数に数式(関数)を使用したコールバック

tara-tail

総合スコア32

ECMAScript

ECMAScriptとは、JavaScript類の標準を定めるために作られたスクリプト言語です。

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2019/08/10 05:59

編集2019/08/15 00:40

問題

vue.jsを勉強していますが、コールバック関数について理解が乏しく、ご教示いただければと思います。

コード

<products.js>

jabascript

1const database = [ 2 { id: 1, name: '商品A', price: 100, content: '商品A詳細' }, 3 { id: 2, name: '商品B', price: 200, content: '商品B詳細' }, 4 { id: 3, name: '商品C', price: 300, content: '商品C詳細' } 5] 6 7export default { 8 asyncFind(id, callback) { 9 setTimeout(() => { 10 callback(database.find(el => el.id === id)) 11 }, 1000) 12 }

<Product.vue>

vue

1<script> 2 import products from 'products.js' 3 export default { 4 props: { 5 id: Number 6 }, 7 data() { 8 return { 9 item: null 10 } 11 }, 12 watch: { 13 id: { 14 handler() { 15 products.asyncFind(this.id, item => { 16 this.item = item 17 }) 18 }, 19 immediate: true 20 } 21 } 22 } 23</script>

現在の状態

「products.js」内のコールバックの引数database.find(el => el.id === id)と、「Product.vue」のproducts.asyncFindの二つ目の引数item => { this.item = item }の関連付けが理解できません。
具体的には、「Product.vue」のproducts.asyncFind{ this.item = item }は、「products.js」内のコールバックに定義されているような記載が無いのですが、この仕組みを理解しておりません。
また、item => { this.item = item }itemは、callbackel(配列)という指しているのでは無いかと、推測しています。

試したこと

コールバック関数に数式(アロー関数)が入っていることで、理解に苦しんでいます。
自分なりに理解を整理するために、コードを変更してみました。
まず、アロー関数に慣れていないので、ES5の記載に変えました。

<products.js>

js

1export default { 2 asyncFind(id, callback) { 3 setTimeout(function() { // アロー関数をES5の書き方に変更 4 callback(database.find(el => el.id === id)) 5 }, 1000) 6 }

<Product.vue>

vue

1<script> 2 import products from 'products.js' 3 export default { 4 props: { 5 id: Number 6 }, 7 data() { 8 return { 9 item: null 10 } 11 }, 12 // 理解できていない「this.item = item」の部分を、関数として独立させました。 13 methods: { 14 xxx(item) { 15 this.item = item 16 } 17 }, 18 watch: { 19 id: { 20 handler() { 21 // 二つ目の引数に、上で追加した関数を指定 22 products.asyncFind(this.id, this.xxx) 23 }, 24 immediate: true 25 } 26 } 27 } 28</script>

こうすることで同じような動きが再現できました。

質問

  1. callbackfunction(元々はアロー関数)でラップされていますが、これは必要なのでしょうか?

  2. this.item = itemが「Product.vue」のcallback(database.find(el => el.id === id)) に定義されていないのですが、これはどういう仕組みになっているのでしょうか(どこからこういう記載が出てくるのでしょうか)?

  3. 最初に載せてある元のソースからですが、「Product.vue」のproducts.asyncFindの第二引数にあるitem =>の部分のitemですが、これは「products.js」のcallbackで定義しているeldatabase配列)と考えてよろしいでしょうか?

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/08/10 10:32

findがわかるなら、callbackに何を渡しているのかもわかるのでは。
tara-tail

2019/08/13 03:47

yukke様。コメントありがとうございます。コまだ質問に至らない記載がありましたら申し訳ありません。
guest

回答1

0

ベストアンサー

  1. callbackがfunction(元々はアロー関数)でラップされていますが、これは必要なのでしょうか?

setTimeoutの第1引数は、関数を渡すことができます。
このとき気をつけなければいけないのは、引数を入れた状態で渡そうとしても、実際渡るのは関数の返り値だということです。

例えば、

JavaScript

1// エラーが起きる 2setTimeout(callback(database.find(el => el.id === id)), 1000);

このように書いてしまうと、実際にsetTimeoutの第1引数に渡るのはcallbackの実行結果なので、エラーになります。
じゃあどうすればいいかというと、無名関数を使います。

JavaScript

1setTimeout(function () { 2 callback(database.find(el => el.id === id)) 3}, 1000);

こうすることで、「callbackに引数を渡して実行する」関数を渡すことができます。
それがアロー関数になると

JavaScript

1setTimeout(() => callback(database.find(el => el.id === id)), 1000);

になります。

  1. this.item = itemが「Product.vue」のcallback(database.find(el => el.id === id)) に定義されていないのですが、これはどういう仕組みになっているのでしょうか(どこからこういう記載が出てくるのでしょうか)?

今回の場合は特に処理がないようですが、基本的にコールバック関数というのは、
非同期処理が終わった時に呼び出してほしい処理を書きますので、
asyncFindが終わり次第やってほしい処理が、そのthis.item = item;だということではないでしょうか。

  1. 最初に載せてある元のソースからですが、「Product.vue」のproducts.asyncFindの第二引数にあるitem =>の部分のitemですが、これは「products.js」のcallbackで定義しているel(database配列)と考えてよろしいでしょうか?

違います。

callback(database.find(el => el.id === id));

なので、database.find(el => el.id === id)の返り値をcallbackの第一引数として渡しています。

投稿2019/08/14 07:18

編集2019/08/15 09:39
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tara-tail

2019/08/15 00:45

yokke_様。ご回答ありがとうございます。詳しいご説明ありがとうございます。最初にyokke_様から投げかけていただいた「findがわかるなら、callbackに何を渡しているのかもわかるのでは。」について、質問の3)として追記させていただきました。もしお手数でなければ、ご確認いただけると幸いです。的外れな質問になっていましたら申し訳ありません。
退会済みユーザー

退会済みユーザー

2019/08/15 09:39

3) について追記しました。
tara-tail

2019/08/17 08:34

yukke_様。3)についてもご回答ありがとうございます。yukke_様からの「基本的にコールバック関数というのは、非同期処理が終わった時に呼び出してほしい処理を書く」というご回答と合わせて、段々と理解してきました。あとは、自分でサンプルを作ったり、他のサンプルを見たりして理解を高めたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問