node.jsでこの関数を非同期にする方法

サンラバー

状況は次のとおりです。node.jsを初めて使用し、次のようなマルチレベルのjsonファイルを含む40MBのファイルがあります。[{}、{}、{}]これはオブジェクトの配列(〜7000オブジェクト)です。各オブジェクトにはプロパティがあり、それらのプロパティの1つはオブジェクトの配列でもあります

ファイルの内容を読み取って反復する関数を作成しました。使いやすさではなく、内容的には欲しいものを手に入れることができました。配列を反復しながらノードが他のWebリクエストを処理できるようにする非同期関数を作成したと思いましたが、そうではありません。誰かが私が間違ったことを教えてくれて、それを書き直して非ブロッキングの反復を行うことができれば、とてもありがたいです。この状況を処理する関数は次のとおりです。

    function getContents(callback) {

        fs.readFile(file, 'utf8', function (err, data) {

            if (err) {
                console.log('Error: ' + err);
                return;
            }

            js = JSON.parse(data);
            callback();
            return;
        });
    }

    getContents(iterateGlobalArr);

    var count = 0;
    function iterateGlobalArr() {

        if (count < js.length) {

            innerArr = js.nestedProp;

            //iterate nutrients
            innerArr.forEach(function(e, index) {

                //some simple if condition here

            });

            var schema = {
                //.....get props from forEach iteration
            }

            Model.create(schema, function(err, post) {

                if(err) {
                    console.log('\ncreation error\n', err);
                    return;
                }

                if (!post) {
                    console.log('\nfailed to create post for schema:\n' + schema);
                    return;
                }
            });

            count++;
            process.nextTick(iterateGlobalArr);
        }
        else {
            console.log("\nIteration finished");
            next();
        }

上記の状況をどのようにテストしたかは明らかです。2つのタブを開きます。1つはこの反復をロードしますが、これには時間がかかり、2つ目は、反復が終了するまでロードされない別のノードルートを使用します。だから本質的に私はブロッキングコードを書いたが、それをリファクタリングする方法がわからない!コールバックですべてが発生しているという理由だけで、別のリクエストを処理するためにイベントループを解放できないのではないかと思います...

JayKuri

あなたのコードはほぼ正しいです。あなたがしているのは、うっかりしてすべてのアイテムを次のティックに追加することです...それでもブロックされます。

重要なコードは次のとおりです。

          Model.create(schema, function(err, post) {

            if(err) {
                console.log('\ncreation error\n', err);
                return;
            }

            if (!post) {
                console.log('\nfailed to create post for schema:\n' + schema);
                return;
            }
        });

        // add EVERYTHING to the very same next tick!
        count++;
        process.nextTick(iterateGlobalArr);

getContents()が実行され、カウントが0のときに、イベントループのティックAにいるとします。iterateGlobalArrと入力し、Model.createを呼び出します。Model.createは非同期であるため、すぐに戻り、process.nextTick()はアイテム1の処理を次のティック(たとえばB)に追加します。次にiterateGlobalArrを呼び出します。これは同じことを行い、アイテム2を次のティックに追加します。ティック、これはまだBです。次に項目3、というように続きます。

あなたがする必要があるのは、カウントインクリメントとprocess.nextTick()をModel.create()のコールバックに移動することです。これにより、nextTickが呼び出される前に現在のアイテムが処理されるようになります...つまり、モデルアイテムが作成された後、次のアイテムが実際に次のティックに追加されます...これにより、アプリはその間に他のものを処理する時間を確保できます。iterateGlobalArrの修正バージョンは次のとおりです。

 function iterateGlobalArr() {

    if (count < js.length) {

        innerArr = js.nestedProp;

        //iterate nutrients
        innerArr.forEach(function(e, index) {

            //some simple if condition here

        });

        var schema = {
            //.....get props from forEach iteration
        }

        Model.create(schema, function(err, post) {

            // schedule our next item to be processed immediately.
            count++;
            process.nextTick(iterateGlobalArr);

            // then move on to handling this result.
            if(err) {
                console.log('\ncreation error\n', err);
                return;
            }

            if (!post) {
                console.log('\nfailed to create post for schema:\n' + schema);
                return;
            }
        });
    }
    else {
        console.log("\nIteration finished");
        next();
    }
}

また、iterageGlobalArrを呼び出すたびに、jsを渡してカウンターすることを強くお勧めします。これにより、iterateGlobalArrのデバッグが非常に簡単になりますが、それは別の話です。

乾杯!

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

Node.jsで非同期関数の結果を表示する方法

分類Dev

Node.jsで非同期関数を処理する方法

分類Dev

Node.jsで非同期関数を処理する方法

分類Dev

Node.jsの非同期関数を作成する方法

分類Dev

Node.jsで非同期関数の長いネストを回避する方法

分類Dev

Node.jsまたはJavaScriptの非同期関数呼び出しを同期関数にラップする方法

分類Dev

Node.jsで同期関数と非同期関数の配列を実行する方法

分類Dev

node.js関数間で変数を非同期に渡す

分類Dev

node.jsの非同期関数から値を返す方法

分類Dev

Javascript / Nodeの非同期関数でAwaitを呼び出した後にタイムアウトする方法

分類Dev

Node.jsで、ミドルウェア関数を非同期で実行することは可能ですか?

分類Dev

node.jsで複数のリターンを非同期的に処理する

分類Dev

node.jsの非同期関数から値を返すことは可能ですか?

分類Dev

2つの非同期関数が終了するのを待ってから、Node.jsで続行します

分類Dev

TypeScriptでnode-postgres非同期クエリ関数を入力する方法は?

分類Dev

node.jsで非同期関数を実行するための時間制限を設定するにはどうすればよいですか?

分類Dev

Node.js / Sequelize.js / Express.js-多対多の関連付けに挿入する方法は?(同期/非同期?)

分類Dev

node-pdfkitで非同期関数をどのように使用しますか?

分類Dev

非同期関数Node.Jsで呼び出される非同期関数

分類Dev

Node / Expressの非同期関数でエラーをキャッチする

分類Dev

node.jsのpromiseと関数を同期する方法

分類Dev

node.js同期関数をラップすると、同等の非同期関数と同じように実行されますか?

分類Dev

node.js同期関数をラップすると、同等の非同期関数と同じように実行されますか?

分類Dev

Node.jsの非同期でAPIデータを取得し、データを取得することで同期する

分類Dev

node.jsで複数のファイルを非同期的に読み取る

分類Dev

async / awaitを使用してnode.jsでReadStreamを非同期的に作成する方法

分類Dev

非同期コールバック関数の値を返すNode.JS関数

分類Dev

Node.jsの非同期関数

分類Dev

node.jsのforeach非同期関数

Related 関連記事

  1. 1

    Node.jsで非同期関数の結果を表示する方法

  2. 2

    Node.jsで非同期関数を処理する方法

  3. 3

    Node.jsで非同期関数を処理する方法

  4. 4

    Node.jsの非同期関数を作成する方法

  5. 5

    Node.jsで非同期関数の長いネストを回避する方法

  6. 6

    Node.jsまたはJavaScriptの非同期関数呼び出しを同期関数にラップする方法

  7. 7

    Node.jsで同期関数と非同期関数の配列を実行する方法

  8. 8

    node.js関数間で変数を非同期に渡す

  9. 9

    node.jsの非同期関数から値を返す方法

  10. 10

    Javascript / Nodeの非同期関数でAwaitを呼び出した後にタイムアウトする方法

  11. 11

    Node.jsで、ミドルウェア関数を非同期で実行することは可能ですか?

  12. 12

    node.jsで複数のリターンを非同期的に処理する

  13. 13

    node.jsの非同期関数から値を返すことは可能ですか?

  14. 14

    2つの非同期関数が終了するのを待ってから、Node.jsで続行します

  15. 15

    TypeScriptでnode-postgres非同期クエリ関数を入力する方法は?

  16. 16

    node.jsで非同期関数を実行するための時間制限を設定するにはどうすればよいですか?

  17. 17

    Node.js / Sequelize.js / Express.js-多対多の関連付けに挿入する方法は?(同期/非同期?)

  18. 18

    node-pdfkitで非同期関数をどのように使用しますか?

  19. 19

    非同期関数Node.Jsで呼び出される非同期関数

  20. 20

    Node / Expressの非同期関数でエラーをキャッチする

  21. 21

    node.jsのpromiseと関数を同期する方法

  22. 22

    node.js同期関数をラップすると、同等の非同期関数と同じように実行されますか?

  23. 23

    node.js同期関数をラップすると、同等の非同期関数と同じように実行されますか?

  24. 24

    Node.jsの非同期でAPIデータを取得し、データを取得することで同期する

  25. 25

    node.jsで複数のファイルを非同期的に読み取る

  26. 26

    async / awaitを使用してnode.jsでReadStreamを非同期的に作成する方法

  27. 27

    非同期コールバック関数の値を返すNode.JS関数

  28. 28

    Node.jsの非同期関数

  29. 29

    node.jsのforeach非同期関数

ホットタグ

アーカイブ