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

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

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

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

JavaScript

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

Q&A

解決済

3回答

1533閲覧

このコードがなぜ動くのか

退会済みユーザー

退会済みユーザー

総合スコア0

ECMAScript

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

JavaScript

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

2グッド

0クリップ

投稿2015/12/28 11:56

javascript

1 2function main(){ 3 a().then(fetch) 4 // console.log(fetch) 5 6} 7function a(){ 8 return fetch("example.com",{method:"get"}).then(function(){return Promise.resolve("twitter.com")}) 9} 10main() 11

これを実行してみるとなぜかmain関数の中のfetchが実行されます。
しかしfetchは関数オブジェクトなはずです。
関数オブジェクトは()がないと動かないと思っているのですがなぜなのでしょうか?

ドキュメントを見ても詳しいものは英文ばかりで・・・

またthenで

ikuwow, sho_cs👍を押しています

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

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

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

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

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

guest

回答3

0

詳しくはPromiseの仕様をググらないとですが、とりあえずなぜ動くかを回答します。

fetch 実行してみると Promise オブジェクトが返って来ていたので、a 関数はfetch()の返り値であるPromiseオブジェクトのthenメソッドを実行してその返り値を返してるわけです。

Promise ではこんな感じでthenをつなげて書けます。

new Promise(function(a){a(1)}) .then(function(b){console.log(b);return 2}) .then(function(c){console.log(c)}) // 1 // 2

a()の返り値を通してますが、単純にthenをメソッドでつないでるのと一緒です。

質問のコードだとこういうことですね。

fetch("example.com",{method:"get"}) .then(function(){return Promise.resolve("twitter.com")}) .then(fetch)

then に渡された関数は内部で実行されます。
なので () はなくても実行されます。

引数に何が入るのかや返り値がどうなるのかは、試してみると結構簡単に理解できると思います。

Promiseに限らず関数を渡すといろいろな条件で実行してくれるのは JavaScript には多いです。

var f = function(x){console.log(x)} ;[1,2,3].forEach(f)

ところでfetch APIってもうつかえたんですね。

投稿2015/12/28 13:34

lazex

総合スコア604

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

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

退会済みユーザー

退会済みユーザー

2015/12/29 01:23 編集

.then(fetch)では上から"twitter.com"という文字列が降ってくると思うのですがこれは内部でどうやって取得しているのでしょうか?
lazex

2015/12/29 12:58

自己解決されたようですが、他の人もみるかもしれないということで、一応回答しときます。 ``` new Promise(function(a){a()}) .then(function(b){return 2}) .then(function(c){console.log(c)}) // 2 ``` の例で分かる通り、return した 2 が次の then の引数に入ります。 また、Promise.resolveの返り値を返した時も同じく 2 が 2 つめの then の引数に入っています。 ``` new Promise(function(a){a()}) .then(function(b){return Promise.resolve(2)}) .then(function(c){console.log(c)}) // 2 ``` Promise.resolve の返り値は Promise オブジェクトなので疑問に思うかもしれませんが、 then の返り値が Promise オブジェクトの場合は、その Promise が成功していれば Promise の値が使われます。 なぜこうなってるかですが then に渡す関数が非同期に何か処理したいときのためです。 ``` new Promise(function(a){a()}) .then(function(b){ console.log(+new Date()) return new Promise(function(resolve){ setTimeout(resolve, 5000) }) }) .then(function(c){ console.log(+new Date()) }) // 1451393635423 // 1451393640433 ``` このように 5秒してから次の then を実行するためにそうなってます。 `Promise.resolve(1)` と `new Promise(function(resolve){resolve(1)})` は一緒です。
guest

0

ベストアンサー

なんだか結局自分でも何が言いたいのかわからなくなってきたので事故解決にします。
fetchがプロミスを返し、thenで取得するのはわかっていたし、thenは第一引数がurlで第二引数がオプションというのは仕様書を見ればかいてありました。

回答していただいた皆様ありがとうございます。

投稿2015/12/29 03:41

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

think49

2015/12/29 04:21 編集

「既知の事実」だけが回答だったとしても解決に至るまでのヒントを貰えたのなら回答された中からベストアンサーを選ぶのが筋ではないかと思います。 少なくとも私なら直接的な回答が得られなくてもヒントを貰っただけでベストアンサーに選びます。 厳しい事をいうようですが、「既知の事実」が初めから質問文に書かれてあれば、回答された方が無駄な回答(記事の事実を指摘する事)をしなくて済んだともいえます。 個人的な見解としては、この質問はメソッドチェーンの仕組みが頭の中で整理できていない事に起因しているような気もしますが…。
KoichiSugiyama

2015/12/29 06:17

自己解決されたのは結構ですが、今後同様の疑問を持った利用者が過去のQ&Aを検索した際に、利用価値のある内容になるように、回答として価値がないベストアンサーが上位に表示されないよう評価を下げさせていただきました。
guest

0

JSあまり詳しくないのですが、回答してみます。
より詳しい解説は、JSに詳しい回答者さまの回答をお待ちいただければ。

これは、コールバックを行うための仕組みのようですね。
コールバックとは、後でその関数を呼び出してもらうために、関数オブジェクトを渡しておく手法です。

おそらく、then関数に関数オブジェクトを渡すことで、then関数の中で任意のタイミングでその関数を呼び出せるようにしているんだと思います。

...

下記のページは、直接の解説があるわけではないですが、参考になるかも知れません。

JavaScript - Promiseと仲良くなって気持ち良く非同期処理を書こう - Qiita
http://qiita.com/progre/items/03626b7f4655007d8cb2

投稿2015/12/28 13:09

argius

総合スコア9388

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問