0

私はこのコードを持っています

function imagenesIn(errU,errores)
    {
        if(errU) throw errU;
        var directorios=new Array();
        var origenDir='';
        var destinoDir='';
        if(errores=='')
        {
            if(campos.img instanceof Array)
            {
                for(file in campos.img)
                {
                    origenDir='';
                    destinoDir='';
                    origenDir=campos.img[file].path;
                    destinoDir='/uploads/publish/alquiler/'+req.session.passport.user+campos.img[file].name;
                    fs.rename(origenDir,process.cwd()+'/public'+destinoDir,function(err)
                    {
                        if (err) throw err;
                        directorios.push(destinoDir);
                        console.dir(directorios)
                    })
                }
            }
        }else{
            res.send(errores)
        }
        return directorios;
    },

campos.img にある req.files.img のすべてのファイル コンテンツの運命の配列をディレクトリに取得したい

しかし、コンソールで印刷すると、これが起こりました

"img": [
  "/uploads/publish/alquiler/andres@hotmail.comTulips.jpg",
  "/uploads/publish/alquiler/andres@hotmail.comTulips.jpg"
],

私はこの結果を得ようとしています

"img": [
  "/uploads/publish/alquiler/andres@hotmail.comTulips.jpg", //first img
  "/uploads/publish/alquiler/andres@hotmail.flowers.jpg"//second img
],

なぜ .push() メソッドは最初の画像ディレクトリのみを配置し、2 番目の画像ディレクトリは配置しないのですか? 私は何かが恋しいですか?

tnx

4

2 に答える 2

3

あなたの問題は

               fs.rename(origenDir,process.cwd()+'/public'+destinoDir,function(err)
                {
                    if (err) throw err;
                    directorios.push(destinoDir);
                    console.dir(directorios)
                })

あなたpush()が実行するまでに実際に実行することはありません

    return directorios;

fs.rename(...)への呼び出しが最後に終了することを確認する必要があります(これはではなく、繰り返します、必ずしも最後に開始される呼び出しと同じになります)、すべての呼び出しが終了した場合を処理する必要があります。非同期呼び出しを使用すると、それらの束を起動した後に失敗して;を実行することはできません。returnすべての作業が完了した後に実行するコードを、先ほど「ハンドル」と呼んだものに対処するコールバックに配置する必要があります。

async.js のような制御フロー ライブラリを使用すると、コードを単純化できますが、関数が非同期になると、それに続くすべてのものも非同期にする必要があるという考えに頭を悩ませる必要があります。

于 2012-09-19T08:52:49.663 に答える
2

エボールマンはほとんどそれを呼んだ。現在、for ループは名前変更関数が終了時に呼び出す無名関数を設定しています。

これらがセットアップされるとすぐに、imagenesIn はディレクトリを返します。戻る前に名前の変更が完了したかどうかに応じて、ディレクトリの一部が含まれているか、まったく含まれていない可能性があります。

ノードの力は、それが非同期であることです。fs.renameSync yes を使用できます。期待どおりになります。ノードは、Apache php サーバーとは異なります。PHP サーバーはリクエストを受け取り、そのリクエスト用に小さなメモリ スライスを予約します。そのため、他のリクエストはすべて独自のメモリを取得するため、引き続き処理できます。ノードはこれを行いません。単一のスレッドで実行され、ブロックしている何か (同期 IO など) を実行すると、他の要求は処理が完了するまで待機する必要があります。

理想的には、imagenesIn も非同期であり、最終パラメーターとして関数を使用する必要があります。関数の基準は、通常、関数 (エラー、データ) に従います。何もなかった場合、エラーは null になります。fs.rename はこのパターンに従います。

また、imagenesIn を呼び出す関数は、理想的にはサーバーの応答を処理する必要があります。これにより、関数を他のタイプのケースで使用できます。エラー時にその特定の応答を送信したくない場合はどうすればよいでしょうか? 応答をまったく送信したくない場合はどうすればよいですか? 現在、これは誤ってヘッダーを 2 回送信する (そしてエラーが発生する) ための良いレシピです。

もしそれが私だったら、これは私があなたの関数を書く方法です(私はテストしませんでしたが、あなたに何らかの方向性を与えるべきです).

function imagenesIn(callback) {

    var directorios=new Array();
    var origenDir='';
    var destinoDir='';
    if(campos.img instanceof Array) {

        function recursion(index){

            //the case that ends the recursion and returns directories
            if (index >= campos.img.length) {
                callback(null, directorios);
                return;
            }

            origenDir=campos.img[index].path;
            destinoDir='/uploads/publish/alquiler/'+req.session.passport.user+campos.img[index].name;

            fs.rename(origenDir, process.cwd() + '/public' + destinoDir, function(err) {

                //the case that ends recursion and sends an error
                if (err) {
                    callback(err);
                    return; 
                }
                directorios.push(destinoDir);
                console.dir(directorios);
                recursion(index++);
            })  
        }

        recursion(0);
    }
    else {
        callback('Campos.img was not an array.');
    }
}

それを呼び出すコードは次のようになります

imagenesIn(function(err, directories) {
    if (err) {
        res.send(err);
    }
    else {
        //do cool stuff with directories.
    }
});

また、for( ; ; ) と for(key in object) の固有の違いを理解していることを確認したかったのです。「for in」は、オブジェクトのキーを繰り返します。これは基本的に数値キーを持つオブジェクトであるため、配列で機能します。しかし、私はこれを行うことができました

var array = ['data', 'data'];
array.nonNumericKey = 'otherdata';

for (var i = 0; i < array.length; i++) の場合、配列データのみを反復処理します。for (key in array) を使用した場合は、nonNumericKey も反復処理します。これが、個人的には、配列ではないオブジェクトに対してのみ「for in」を使用する理由です。

于 2012-09-20T04:43:35.793 に答える