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

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

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

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

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

Q&A

解決済

1回答

1717閲覧

ブロッキング関数を作成したい node.js

onigiriZ

総合スコア3

Node.js

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

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

0グッド

0クリップ

投稿2021/08/30 07:02

やりたいこと

nodejsでサーバー開発をしています。
その中で、同時に多くの接続があった場合でも、1つずつ処理したい関数があります。
(イメージとしては、同時に多くの接続が来ても、順番に処理したい)

そこで、
execSyncやfs.readFileSyncのようなブロッキング処理を行える関数を自作したい状況です。

promissやasync/awaitでは、そのような制御はできませんでした。

1 ブロッキング処理を実現できるライブラリ
2 そのほかの手法
を探しています。

実装方法をご存じの方いましたら、教えていただきたいです。
よろしくお願いします。

開発環境

node.js v16.5.0

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

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

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

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

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

guest

回答1

0

ベストアンサー

Webは不特定多数からのリクエストを取り扱う為にわざわざ順不同にしているので
それに逆らうならそれなりの意味があるはずです。
そしてその「逆らう要望」の内容により取るべき手段が変化します。

例えばMySQLのコネクション枯渇問題で排他制御を入れたいのなら
コネクションプールを利用するべきです。

promissやasync/awaitでは、そのような制御はできませんでした。

可能です。

原理としてはpromiseを定義する時
`const promise = new Promise(resolve => {実行内容});
こんな風にresolve関数を定義しますが、これを外部に持ち出す事で
関数の外部でresolveを叩いてpromiseを完了させる事が可能となります。

bash

1$ node 2Welcome to Node.js v14.17.4. 3Type ".help" for more information. 4 5> state = {} 6{} 7 8> promise = new Promise(resolve => {state.resolve = resolve}) 9Promise { <pending> } 10 11> promise 12Promise { <pending> } 13 14> state.resolve() 15undefined 16 17> promise 18Promise { undefined } # <- 終了していることが確認出来る

要は各リクエストを数珠つなぎにしていくだけです。

js

1Promise.resolve(null) 2 .then(() => { 3 // resolveを外に取り出す 4 // 1個目のリクエストを良い感じに完了させる 5 }) 6 .then(() => { 7 // resolveを外に取り出す 8 // 2個目のリクエストを良い感じに完了させる 9 }) 10 .then(() => { 11 // resolveを外に取り出す 12 // 3個目のリクエストを良い感じに完了させる 13 })

Promiseは後から追加することも可能です。

js

1let promise = Promise.resolve(null); 2 3for (let i = 0; i < 3; i++) { 4 promise = promise.then(() => { 5 // resolveを外に取り出す 6 // i個目のリクエストを良い感じに完了させる。 7 }) 8}

後はresolveの持ち出しと
Promiseの数珠つなぎを駆使して何とか書ききれば出来ます。

この辺は配給の列を準備するラッパーみたいな関数を用意して
これが全部完了したら貴方は動いても良いぞみたいな所までこぎつければ完了ですね。

js

1const express = require("express"); 2 3const lineUp = () => { 4 // 上記のresolve持ち出しを駆使して取り出す 5 return resolve; 6} 7 8const app = express(); 9app.get("/", async (req, res) => { 10 // これで後続のリクエストを待たせる 11 const resolve = await lineUp(); 12 13 // DB等のアクセスで欲しいデータを用意する 14 const data = {name: "taro"}; 15 16 // resolveを実行してブロッキングを開放 17 resolve(); // どんなエラーが発生してもこのresolve関数は実行しておきたい 18 res.json(data); 19});

ここのコアな部分を作るのはかなり面倒というか、
実装の手間と工数が必要ですし、リクエストが集中した時のメモリリーク対策等
まともに書いてたらキリないですし、責任も取れないのでぼかした感じで終了します。

投稿2021/08/31 02:42

miyabi-sun

総合スコア21418

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問