2012-09-19 3 views
0

이 코드를 가지고array.push가 작동하지 않는 이유는 무엇입니까?

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; 
    }, 
내가 directorios에 campos.img

에 req.files.img 에있는 모든 파일 내용의 운명의 배열을 얻고 싶은

하지만 난에 인쇄 할 때 문제는이 결과

"img": [ 
    "/uploads/publish/alquiler/[email protected]", //first img 
    "/uploads/publish/alquiler/[email protected]"//second img 
], 
을 얻으려고 노력

"img": [ 
    "/uploads/publish/alquiler/[email protected]", 
    "/uploads/publish/alquiler/[email protected]" 
], 

메신저 무슨 일이 생긴 콘솔

.push() 메서드는 첫 번째 이미지 디렉토리 만 놓고 두 번째 파일을 넣지 않는 이유는 무엇입니까 ??? 나는 무엇인가 놓친다? ???

TNX

답변

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와 같은 제어 흐름 라이브러리는 코드를 단순화 할 수 있지만 함수가 비동기가되면 비동기 적이어야한다는 개념을 염두에 두어야합니다.

+0

fs.renameSync-로 해결할 수 있습니까? – andrescabana86

+0

tnx all ... renameSync()로 해결할 수 있습니다. – andrescabana86

2

꽤 많이 불렀다. 지금 for 루프는 이름 바꾸기 함수가 끝나면 호출 할 익명 함수를 설정하고 있습니다.

이러한 설정이 완료되면 imagenesIn이 디렉토리를 반환합니다. 반환 전에 이름 변경이 완료되었는지 여부에 따라 디렉토리의 일부 또는 모두를 포함 할 수 있습니다.

노드의 강력 함은 비동기입니다. fs.renameSync yes를 사용할 수 있으며 예상 한대로 작동합니다. 노드는 아파치 PHP 서버와 다르다. PHP 서버가 요청을 받고 요청에 대해 작은 메모리 조각을 예약합니다. 따라서 다른 요청은 모두 자체 메모리를 가지기 때문에 계속 처리 할 수 ​​있습니다. 노드는 이것을하지 않습니다. 그것은 하나의 스레드에서 실행되며 (동기 IO와 같은) 차단중인 작업을 수행하는 경우 다른 요청은 완료 될 때까지 기다려야 처리가 가능합니다.

imagenesIn은 비동기 적이어야하며 함수를 최종 매개 변수로 사용하는 것이 가장 이상적입니다. 함수의 표준은 대개 함수 (오류, 데이터)를 따릅니다. 존재하지 않았던 경우는, 에러가 null가 아니면 안됩니다. fs.rename은이 패턴을 따릅니다.

또한 imagenesIn을 호출하는 함수는 서버 응답을 이상적으로 처리해야합니다. 이렇게하면 다른 유형의 케이스에서 함수를 사용할 수 있습니다.오류로 인해 특정 응답을 보내지 않으려면 어떻게해야합니까? 응답을 보내지 않으려면 어떻게해야합니까? 지금은 실수로 헤더를 두 번 보내고 (오류 발생) 좋은 방법입니다.

내 경우,이 기능을 작성하는 방법입니다 (테스트하지는 않았지만 어떤 방향을 제시해야합니다).

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 in"은 객체의 키를 반복합니다. 기본적으로 숫자 키가있는 객체이기 때문에 배열에서 작동합니다. 당신이 그랬다면 나는이 그러나

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

을 할 수있는 (var에 나는 = 0; 나는 < 사항 Array.length, 내가 ++), 당신은 단지 배열 데이터를 반복합니다. for (key in array)를 사용했다면 nonNumericKey를 반복 할 수도 있습니다. 이것이 개인적으로 배열이 아닌 객체에서만 "for for"를 사용하는 이유입니다.

관련 문제