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

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

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

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

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Q&A

2回答

717閲覧

JavaScriptの非同期処理(Promise)の使い方が分からない

pinsan

総合スコア3

JavaScript

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

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

0グッド

1クリップ

投稿2021/06/17 17:15

分からないこと

JavaScriptの非同期処理(Promise)の使い方がさっぱり分かりません。
実際に試してみようと思って、以下のコード

Javascript

1const promise = new Promise((resolve)=>{ 2 console.log("1番目"); 3 resolve();}) 4 5 .then(()=> 6 {setTimeout(()=>{ 7 console.log("2番目")},1000); 8 return 1;}) 9 10 .then(()=>{ 11 console.log("3番目"); 12 return 1;}) 13 14 .catch((e)=>{ 15 console.log("error")}) 16 17 console.log("1番目");

を書いてみたのですが、結果は、

Javascript

11番目 23番目 32番目

とただの同期処理になってしまいます。
一応色々なサイトを見てはみたのですが、何が問題かも理解できず…
Promiseの使い方というところに関して

  • resolveとreturnそれぞれの使い所、使い分け
  • Promise(()=>{})や.then(()=>{})と書いた時、左の()に引数を明記するのはどんな時か
  • 以下のコードのように

 ```JavaScript
function A(val){
return new Promise(function(resolve,reject){
if(val){
setTimeout(function(){
resolve()},1000)
}else{
reject();
}})}

 **と最初に関数Aの返り値をPromiseにして、その後"A.then"と書くことがあるがそれはどのような時か?(そのように書くメリット?)** 以上3点も含めて教えていただけると非常に有り難いです。よろしくお願いいたします。 # 環境 macOS Mojave 10.14.6 IDE->Visual Studio Code でjsファイルを作ってnodeで実行しています

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

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

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

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

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

guest

回答2

0

少しPromiseについて混乱されているのかもしれません。

そもそもPromiseとは何か?から説明させてください。

Promiseは「今は分からなくても後からわかる値」を表したデータです。

通常のプログラミングおいて、例えば次のようなプログラミングがあったとします。

js

1// 0 ~ nまでの和を計算する関数 2function sum(n){ return [...Array(n+1).keys()].reduce((x,y)=>x+y); } 3const data = sum(1000);

このプログラムが実行された時点で、dataに500500という数字が入っているはずです。なぜなら、sum(1000);の関数呼び出しがその計算が終わるのを待ってから、その結果をdataに入れるからです。

この計算または処理が終るのを待つのは、たとえ、それがいくら時間かかっても待ってしまいます。

javascript

1const data = waitVeryLongTime(); //すごく長く待たないといけない関数。 2waitedProgram(); // 待たされるプログラム

いくら時間がかかろうと、処理や計算などが終わらない限り次に進めないのです。それは困りましたね。このあとの、waitedProgram()もまた、waitVeryLongTime()が終わらないと実行されないのです。たとえ、実行するのに、waitVeryLongTime()のデータが必要無かったとしてもです。

そこで、javascriptではPromiseというものを用意しました。先ほども言いました通り「今は分からなくても後からわかる値」のことです。

たとえば次のコードがあったとしましょう

javascript

1const data = returnPromiseFunc(); // Promise(今は分からなくても後からわかる値)を返す関数 2noWaitedProgram(); //またなくていい!

このreturnPromiseFunc()はPromiseを返すとしましょう。

このときreturnPromiseFunc()計算や処理の途中であってもデータを返すことができます。なぜなら、Promiseは「(計算や処理の途中だから)今は分からないけど、後からわかるよ」というデータだからです。

そしてそのままreturnPromiseFunc()は計算が途中のままのデータを返します。その途中の計算はPromiseが引き継ぎます。そして、dataがそのPromiseを受け取ります。

dataに「(途中の計算だけど)Promiseというデータが返ってきた」というので、その次のnoWaitedProgram();に進めるわけです。

さて、dataはPromiseオブジェクトが渡されました。もしPromiseの内部にある計算が終わった「後からわかるデータ」を使いたいと思ったとしましょう。でもこのままだとデータは使えません。

そこで.then()というメソッドが出てくるわけです。

javascript

1// .thenは、Promiseの中の計算が終わった時何をやるかを記述するためのもの 2data.then((resultData)=>{ 3 console.log(resultData); 4});

このように書くことによって、resultDataという引数に、「後から分かるデータ」がやってくるわけです。

また、「後から分かるデータ」は必要ないけど、そのPromiseが完了したタイミングで処理をしたいときもあるでしょうその時は、

// 終わった後のデータが要らないとき data.then(()=>console.log("Promise resolved!"));

のように書きます。

さて、次にnew Promise((resolve)=>{}) を使うときを紹介しましょう。PromiseはもともとJavascriptには無かったものでした。Promiseが無かった時代の以前のJavascriptは、このような「今は分からないけど後で分かる」みたいな処理をコールバックを使って処理していました。

次のように書いていました。

javascript

1// 関数の引数に直接「後から分かった後の処理をする関数」を渡す 2callbackFunction((resultData)=>{ console.log(resultData); }); 3

このように計算が終わった後の処理をするコールバック関数を予め渡してあげることによって、計算が終わった後のデータの処理をしていました。

何が違うかと言えば、返り値が無いのです。Promiseが無い、つまり「今は分からないけど後で分かる」というものが無いので何も返しようがないのです。もし値を返したいのであれば、計算が終わるまで待つ必要がありました。

このような関数の典型例がsetTimeoutです。

javascript

1// 1000ms後の処理をする関数を渡して、 2setTimeout(()=>{ 3 /// code... 4},1000)5noWaitProgram(); // もちろん1000ms待たなくていい 6

setTimeoutは、「計算(ただ待つというだけの処理)が途中であっても」関数を抜け出して次の処理に行きます。待つ後の処理はコールバックに任せるからです。

Javascriptにはこのような非同期のコールバックを受け取る関数によって非同期処理を書いていました。new Promiseはこようなコールバックを受け取る関数から、Promiseを返す関数にラップするのに使います。

javascript

1// setTimeoutをPromiseを返す関数にする 2function timeout(ms){ 3 // promiseを作って、「今は分からないけど後から値が分かる」データをつくる 4 const promise = new Promise((resolve)=>{ 5 setTimeout(()=>{ 6 resovle(); // ここで値が分かる(処理が終わる) 7 }, ms); 8 }); 9 // データを返す 10 return promise; 11} 12 13timeout(1000).then(()=> console.log("1000ms秒後だ"); );

これで、Promiseの基本的なこと、thenを使う基本的な意味、 new Promise((resovle)=>{})を使うときを説明しました。

あとは、やらないといけないことはPromiseチェーンについてです。

先ほど.thenについて話しました、あと大事なのは.then自体の返り値についてです。

javascript

1data.then((resultData)=> console.log(resultData) );

と書きました。実を言えば、この式によって返されるデータもまたPromiseなのです。

javascript

1let data2 = data.then((resultData)=> console.log(resultData); ); 2data2.then(()=> console.log("..."); });

上記の式でいえば、data.then()の返り値もまたPromiseになります。なので、このPromiseもまた、thenで、「後から分かるデータ」を受けとることができます。そのデータはdata.then((resultData)=>{ ... });でthenに渡された関数の返り値です。

例えば次のように書いたとしましょう

javascript

1const data2 = data.then((resultData)=>{ return 1; }); 2data.then((resultData2)=>console.log(resultData2); });

このときにresultData2に渡される「後から分かる」データは1になります。

更に、.thenのに渡された関数の返り値がPromiseだったとしましょう。これはそのPromiseがthenの戻り値になります

javascript

1const data2 = data.then((resultData)=>{ return 1; }); 2data2.then((resultData2)=>{ return timeout(1000); });

わかりやすさのため、返り値を一旦変数に渡して、それからthenにつなげるように書いていますが、実際には、thenは必ずPromiseを返すため、このように書くことができます。

javascript

1 returnPromiseFunc() 2.then((data1)=>{ 3 return data1 + 1; 4}) 5.then((data2)=>{ 6 return returnPromiseFunc2(data2); 7}) 8.then((data3)=>{ 9 console.log(data3); 10});

このようにPromiseにthenで繋げて書くことをPromiseチェーンと言います。このように書くことによって、非同期処理が(コールバックを受け取る非同期関数と比べて)書きやすくなったのです。

以上によりPromiseの基本的なことは述べました。最後に質問者の太字に答えて終わります。

resolveとreturnそれぞれの使い所、使い分け

「この使い分け」と言いますが実際には「使い分け」ということを聞くこと自体がズレているように感じます。全く別物なのです。

ただそれぞれをまとめるとこうでしょう。

  • returnは関数の戻り値を記述し、関数の呼び出し元へ処理を返すもの。関数定義の中でつかう。

  • resolveは、Promiseを作るときに、Promiseが受け取る関数の名前でよく使われるもの。(べつにresolveでなくてもいいです。)resolve(data)を書くことによって、Promiseの「後で分かる」値を指定できる。new Promise((resolve)=>{})の中でつかう。

Promise(()=>{})や.then(()=>{})と書いた時、左の()に引数を明記するのはどんな時か

Promiseの「後で分かる値」を次の処理に使いたいときです。

と最初に関数Aの返り値をPromiseにして、その後"A.then"と書くことがあるがそれはどのような時か?(そのように書くメリット?)

Promiseを使えるようになることです。Promiseを使うことによって、非同期処理がより書きやすくなります。

async/awaitもPromiseをベースとしています。なので、async/awaitを使う上でも、Promiseの理解があると、書きやすくなると思います。

投稿2021/06/17 21:26

nobkz

総合スコア320

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

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

0

命題の流れですとこんな感じになります

javascript

1new Promise((resolve)=>{ 2 console.log("1番目"); 3 resolve(100); 4}).then((res)=>{ 5 console.log(res); 6 return new Promise((resolve)=>{ 7 setTimeout(()=>{ 8 console.log("2番目"); 9 resolve(200); 10 },1000); 11 }); 12}).then((res)=>{ 13 console.log(res); 14 console.log("3番目"); 15});

投稿2021/06/18 00:34

yambejp

総合スコア114839

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問