【问题标题】:why array.push doesnt work?为什么 array.push 不起作用?
【发布时间】:2012-09-19 08:36:47
【问题描述】:

我有这个代码

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;
    },

我想在directios中获取req.files.img中所有文件内容的命运数组 在 campos.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() 方法只放第一个图像目录而不放第二个??? 我想念什么???

tnx

【问题讨论】:

    标签: javascript node.js express


    【解决方案1】:

    你的问题是在

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

    您的 push() 不会在您运行时真正运行

        return directorios;
    

    您需要确保对fs.rename(...) 的调用最后完成(这是不是,我重复不是,一定会是 starts 最后的同一个调用)处理所有调用都已完成的情况。使用异步调用,您不能在启动一堆它们并执行return 之后就失败了;在完成所有工作后,您必须将要运行的代码放在一个回调中,该回调解决了我之前所说的“句柄”。

    像 async.js 这样的控制流库可以简化您的代码,但您需要理解这样一个概念,即一旦您的函数变为异步,其后面的所有内容也必须是异步的。

    【讨论】:

      【解决方案2】:

      ebohlman 几乎称它为。现在,您的 for 循环正在设置重命名函数完成后将调用的匿名函数。

      这些设置完成后,imagenesIn 将返回目录。它可能包含部分目录,也可能不包含目录,具体取决于您返回之前是否完成重命名。

      节点的强大之处在于它是异步的。您可以使用 fs.renameSync 是的,它会按照您的预期进行。 Node 不像 apache php 服务器。 php 服务器收到一个请求,并为该请求保留一小块内存。这就是为什么仍然可以处理其他请求的原因,因为它们都有自己的内存。节点不这样做。它在单个线程上运行,如果您执行任何阻塞操作(如同步 IO),其他请求必须等到它完成才能处理。

      理想情况下,您的 imagenesIn 也应该是异步的,将函数作为最终参数。函数的标准通常遵循函数(错误,数据)。如果没有,则错误应该为空。 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( ; ; ) 和 for(key in object) 之间的独特区别。 “For in”遍历对象的键。这适用于数组,因为它本质上是一个带有数字键的对象。不过我可以这样做

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

      如果你这样做了 (var i = 0; i

      【讨论】:

        猜你喜欢
        • 2015-09-12
        • 1970-01-01
        • 2020-10-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-20
        • 2017-04-24
        相关资源
        最近更新 更多