🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
並列処理

複数の計算が同時に実行される手法

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

非同期処理

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

Q&A

解決済

2回答

964閲覧

async と await の処理について、eval 以外の解決策を知りたいです

tarakorakko

総合スコア13

並列処理

複数の計算が同時に実行される手法

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

非同期処理

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

0グッド

1クリップ

投稿2020/11/26 14:45

編集2020/11/26 15:44

###実現したいこと
該当のソースコードで次のように並列で処理しています。

js

1 Promise.all([ 2 wrap( func1 ), // 引数を渡したい 3 wrap( func2 ) 4 ])

これに引数'apple'を渡して次のような実行をしたいのですが、こうするとエラーになります。

js

1 Promise.all([ 2 wrap( func1('apple') ), // こうするとエラー 3 wrap( func2 ) 4 ])

###該当のソースコード
以下の11行目が引数'apple'を渡したい行です。

ソースコードを実行する

js

1// func1, func2 を並列処理しつつ、結果は順次処理していく 2$(function() { 3 4 // 結果は順次処理 5 const wrap = async function(func) { 6 const res = await func(); 7 console.log(res); 8 return res; 9 } 10 11 // func1, func2 を並列処理 12 console.log("並列処理開始"); 13 Promise.all([ 14 wrap( func1 ), // 引数を渡したい 15 wrap( func2 ) 16 ]).then(res=>{ 17 console.log(res); 18 console.log("並列処理すべて終了"); 19 }); 20 21 // AJAXでデータを取得 22 function func1(str=''){ 23 var def = new $.Deferred(); 24 console.log('start func1') 25 setTimeout(function(){ 26 const ajaxResponse1 = [{name:str+'太郎'},{nane:str+'次郎'}]; 27 def.resolve( ajaxResponse1 ); 28 },1000); 29 return def.promise(); 30 } 31 32 // AJAXでデータを取得 33 function func2(){ 34 var def = new $.Deferred(); 35 console.log('start func2'); 36 setTimeout(function(){ 37 const ajaxResponse2 = [{name:'花子'},{nane:'良子'}]; 38 def.resolve( ajaxResponse2 ); 39 },2000); 40 return def.promise(); 41 } 42 43});

###発生している問題・エラーメッセージ
引数'apple'を渡すと次のエラーになります。

Uncaught (in promise) TypeError: func is not a function

###考察・試したこと
正しいかわかりませんが、
wrap( func1 )

wrap( func1('apple') )
とすると、wrapの中で()があるためにこの時点で関数func1が実行されてしまうことが原因か?と考えています。

なので
wrap( "func1('apple')" )
という風に文字列で渡すようにして、evalで文字列を関数として処理する方法を試しました。

js

1$(function() { 2 3 // 結果は順次処理 4 const wrap = async function(func) { 5 const res = await eval(func); // evalで文字列を関数として処理する 6 console.log(res); 7 return res; 8 } 9 10 // func1, func2 を並列処理 11 console.log("並列処理開始"); 12 Promise.all([ 13 wrap( "func1('apple')" ), // 文字列で渡す 14 wrap( "func2()" ) // 同じく文字列で渡す 15 ]).then(res=>{ 16 console.log(res); 17 console.log("並列処理すべて終了"); 18 }); 19 20/*-- 以下略 --*/

###質問
これによって実現できたように思えるのですが、evalは避けるべきとの記事を方々で目にします。

そこでevalを使うことなく引数'apple'を渡す方法を知りたいのですが、そのようなことは可能でしょうか?

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

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

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

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

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

guest

回答2

0

何をしたいのかいまいちわかりませんが、wrap(func1.bind(this, 'apple'))とかwrap(()=>func1('apple'))とかすればできるかと思います。

投稿2020/11/26 15:00

raccy

総合スコア21737

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

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

tarakorakko

2020/11/26 15:56 編集

できました!ありがとうございます! https://jsfiddle.net/dfguet96/ わかりにくかったですよね。少しコメントアウトを追加しておきました。
guest

0

ベストアンサー

wrap( func1('apple') )
とすると、wrapの中で()があるためにこの時点で関数func1が実行されてしまうことが原因か?と考えています。

当たってると思います。

たぶん、↓こんな風に書きたいのでは?

javascript

1wrap(func1, 'apple'), 2wrap(func2), 3wrap(func3, 'banana', 'orange'), 4...

もしそうなら、
wrap()関数が、funcと任意数の引数(つまり可変長引数)を受け取れるようにすれば良いですね。

以下、サンプルです。

javascript

1const w = function(f, ...args) { 2 // ↑引数が何個来ようとも、 3 // ↓それらを引数にしてfを呼ぶ。 4 let res = f(...args); 5 return res; 6} 7 8function f1(s) { return '[' + s + ']'; } 9function f2() { return 'f2'; } 10function f3(s, t) { return s + ', ' + t; } 11 12w(f1, 'apple'); //=> "[apple]" 13w(f2); //=> "f2" 14w(f3, 'banana', 'orange'); //=> "banana, orange"

投稿2020/11/26 15:41

gpsoft

総合スコア1323

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

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

tarakorakko

2020/11/26 15:47

なるほど関数と引数をそれぞれ渡し、引数は可変ですか。 うーん勉強になります。ありがとうございます。
tarakorakko

2020/11/26 16:02 編集

仰る方法でできました!ありがとうございます! https://jsfiddle.net/1b9Lfdw4/ 可変長引数で渡せると、wrapの中で引数をいじれる点が便利でしたので、ベストアンサーにさせて頂きました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問