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

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

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

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

同期

複数のディレクトリに存在するファイルを更新した場合に、すべてのファイルにも更新が行われる事、又は、同じ記憶領域に同時にアクセスして内容の整合性が失われてしまう事をを防ぐ制御などを同期と呼びます。

Q&A

2回答

1333閲覧

[Node.js]外部ファイルの同期処理がわからない

aiai8976

総合スコア112

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

同期

複数のディレクトリに存在するファイルを更新した場合に、すべてのファイルにも更新が行われる事、又は、同じ記憶領域に同時にアクセスして内容の整合性が失われてしまう事をを防ぐ制御などを同期と呼びます。

0グッド

0クリップ

投稿2020/01/12 14:15

前提・実現したいこと

Node.jsで外部ファイル(node)と連携したプログラムを書いています。
以下のようなソースコードですが、awaitの関数の中で、外部ファイルを呼び出してさらに待ちたい時にはどのように記述すれば良いでしょうか。外部ファイルをPromiseにすればrequireなどが変わるため、混乱しています。
わかる方がいましたらコメントお願いします。

該当のソースコード

main.js

var file = require('../sample/sample.js'); function get_ave(){ return new Promise(resolve=>{ var temp = file.ave///////待ちたい resolve(temp) /////////値が入るのを待たずにresoleしてしまう }) } const main = async()=>{ const get_hoge = new Promise(resolve=>{ get_ave.then( ) . . . }); const result=await get_hoge; } main();

sample.js

. . . ///平均を求める。数秒かかる。 exports.ave=ave;

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

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

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

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

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

guest

回答2

0

Node.jsのバージョンによって使えるかどうかが変わりますが、requireではなくimport()として、読み込み自体がPromiseを返すようにしてみてはどうでしょうか。

投稿2020/01/13 00:32

maisumakun

総合スコア145123

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

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

aiai8976

2020/01/13 07:04

なるほど。requireとimportの違いは何でしょうか?
aiai8976

2020/01/13 07:10

調べてみたところimport().thenでPromiseを使って非同期で実行できるみたいですね。これを同期的に実行することは可能でしょうか。
maisumakun

2020/01/13 07:37

そもそも論として、「require/importしただけで外部ファイルを読みに行って、しかも結果を非同期で返す」という、sample.jsの書き方自体が適当ではないです。
aiai8976

2020/01/13 08:11

外部のファイルを読み込んで同期的に処理したい時の適切な書き方はどういうものでしょうか。
maisumakun

2020/01/13 08:14

fsモジュールにはsync系のメソッドがありますので、それらを使って操作しましょう。
maisumakun

2020/01/13 08:16

「外部ファイルをPromiseにすればrequireなどが変わる」ほうが、状況として適切かもしれません。
aiai8976

2020/01/13 08:18

fsって取得したデータを書き込んだり読み込んだりするイメージなのですが、fsで読み込んだファイルのプログラムを実行することも可能なのでしょうか。
maisumakun

2020/01/13 08:23 編集

「数秒かかる」処理の内容が、外部のデータファイルを取得してそれを計算するものだと考えていたのですが、違うのですか?
aiai8976

2020/01/13 08:21

外部ファイルでPromiseを返すようにすると、呼び出し元でasync/awaitを使いたいのですが、awaitで呼び出している関数(get_ave)をasync関数にしてawaitで外部を呼び出すという二重な書き方は正しいのでしょうか。
aiai8976

2020/01/13 08:25

電波強度の取得なのでもう少し複雑になっています。aveに値が入るまで待つような処理にしたいです。
maisumakun

2020/01/13 08:25

確認ですが、「数秒かかる」要因は「sample.js自体が巨大で読み込み時間がかかる」「sample.jsでの、外部資源を使わない計算処理」「sample.jsから外部のデータファイルなどI/Oアクセスがある」のどれでしょうか?
aiai8976

2020/01/13 08:28

「sample.jsでの、外部資源を使わない計算処理」だと思います。
maisumakun

2020/01/13 08:28

> 電波強度の取得なのでもう少し複雑になっています。aveに値が入るまで待つような処理にしたいです。 ありがとうございます。では、「強度そのもの」をexportするのではなく、「強度を返すPromise」をexportして、それをrequireで取った側では、そのPromiseをthenなりawaitなりで待つほうがいいかと思います。
aiai8976

2020/01/13 08:32

となると、上のmain.jsのなかでget_aveの中のPromiseの中で待つことになると思いますが、awaitに指定した関数をasyncにして、呼び出す外部ファイルをawaitに指定するような二重なことはできるのでしょうか。
maisumakun

2020/01/13 08:36

> となると、上のmain.jsのなかでget_aveの中のPromiseの中で待つことになると思いますが そんなまどろっこしいことをする必要はありますか?そのままPromiseを引き回せばいいだけかと思います。
aiai8976

2020/01/13 08:38

そのイメージがつかめていません。よろしければ具体的なコードで説明していただけると大変助かります。
maisumakun

2020/01/13 08:40

exportするものがPromiseであれば、「呼び出す外部ファイルをawaitに指定する」必要はありません。そのままrequireで大丈夫です。
aiai8976

2020/01/13 08:43

それだと非同期処理になりませんか?
aiai8976

2020/01/13 09:04

すいません。resolveが返るまでは待つので大丈夫ですね。
guest

0

NodeJS v8以降標準モジュール utils.promisify があり、NodeJS特有の作法に従った(コールバックを引数に与える)メソッド(例えば、fs.read() など)は Promise化 できます。

javascript

1let util = require("util"); 2let fs = require("fs"); 3 4let pfs = {}; 5pfs.read = util.promisify( fs.read ); 6// pfs.read( filepath ); Promise を返却する

ご質問のコードの get_ave() の意図は、よく分かっていませんが,以下のように使えるのではないでしょうか。

javascript

1var file = require('../sample/sample.js'); 2 3function get_ave(){ 4 return pfs.read(file.ave); 5}

投稿2020/01/12 21:30

AkitoshiManabe

総合スコア5432

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

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

aiai8976

2020/01/12 23:05

今回、外部ファイルから渡したいのは平均値なのですが、fs.readの箇所にaveとすれば大丈夫ですか?
AkitoshiManabe

2020/01/13 00:59

fs.read は ファイルの内容を読むものですので、file.ave にはpathがあるものと思って回答しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問