###やりたいこと
コールバック部分の無名関数を、名前付きの関数に置換したいと考えています。
###元のコード
<products.js>
js
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> に以下のfind関数を追記し、asyncFindからcallbackを削除し、find関数を配置しました。これで、無名関数を使用していた時と同じように動くと思いましたが、<Product.vue> で商品名などが表示されませんでした。
<products.js>
js
1export default { 2 find(id) { // 追記した関数 3 return database.find(el => el.id === id) 4 }, 5 asyncFind(id) { 6 setTimeout(() => { 7 return this.find(id) // callbackを削除してfind関数を配置 8 }, 1000) 9} 10
<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 // ここを書き換えて、asyncFindからの戻り値を、`this.item`に格納しようとした 16 this.item = products.asyncFind(this.id) 17 }, 18 immediate: true 19 } 20 } 21 } 22</script>
###質問
そもそも、<products.js> の無名関数部分を、名前付きの関数に置換するのが間違っていたのか、それとも私のコードの考え方・書き方に間違えがあるのか、ご指摘していただけると助かります。
this.find(id)
↑この this には何が入っているのですか? アロー関数は this を束縛しないので、ご提示の部分だけではわからないと思うのですが。
また、
asyncFind(id, callback) {}
の第2引数が削除されていますが、これは、this.findと同じものなのですか?
あ、Product.vue も書き換えているのですね。失礼しました。
そうすると、その部分の this が一致するのかが気になりますね。
Lhankor_Mhyさん、ありがとうございます。私がthisの使い方を間違っていると思います。ここの場合は、アロー関数内なので、thisはwindowオブジェクトを参照してしまいますよね?コードを書き換えますので、再度ご確認いただき、お手数ですが再度ご指摘ください。
thisは、find関数を指しているつもりです。もしかしたら、不要なのかもしれません。
this.item = products.asyncFind(this.id)
とありますが、これは products.asyncFind の戻り値を this.item に代入するということになるかと思います。
一方で、asyncFind には return 文がありませんから、undefined を返すと思います。
そこに問題がありそうな気がしますが……
Lhankor_Mhy様。find関数にreturnがあるので、てっきりasyncFindからも値が戻ると思っていたのですが、勘違いだったようです。
asyncFindから、ちゃんと値が戻るようにするにはどうしたら(どこにreturnを書けば)良いでしょうか?たびたび申し訳ありません。
非同期なので、handler の中で代入するには、async await で書くしかないと思いますが……
asyncFind に引数で this を渡して、そちら側で代入するのではダメなのですか?
Lhankor_Mhyさん、ありがとうございます。ちょっと私の頭では理解できておりません。thisを渡すというのは、<products.js> のasyncFind の引数に「asyncFind (id, this)」のようにするのでしょうか?
そうですね。そちら側の this と一致するなら必要ないですが、おそらく異なるのではないですか?
Lhankor_Mhyさん、<Product.vue> の「this.item」に値を渡すには、callback関数でないと難しいみたいですね。諦めて、元のコードに戻そうと思います。ありがとうございました。
お力になれずすみません。
目的に合うのかわかりませんが、callback を残していいなら、
find(id) { // 追記した関数
return database.find(el => el.id === id)
},
asyncFind(id, callback) {
setTimeout(() => {
callback( this.find(id) )
}, 1000)
}
でもいいのかもしれませんね。
回答1件
あなたの回答
tips
プレビュー