简体   繁体   English

为什么array.push不起作用?

[英]why array.push doesnt work?

i have this code 我有这个代码

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

i want to get in directorios an array of the destiny of all files content in req.files.img that are in campos.img 我想在Directorios中获得campos.img中req.files.img中所有文件内容的命运数组

but when i print in console this happend 但是当我在控制台中打印时

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

im trying to get this result 我试图得到这个结果

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

why .push() method put only the first image directory and not the second??? 为什么.push()方法仅放置第一个图像目录,而不放置第二个图像目录??? i miss something??? 我想念东西吗?

tnx TNX

Your problem is that in 你的问题是

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

your push() won't have actually run by the time you do 您的push()实际不会在您运行时运行

    return directorios;

You need to make sure that the call to fs.rename(...) that finishes last (which is not , I repeat not , necessarily going to be the same call that starts last) handles the case where all the calls have finished. 您需要确保调用fs.rename(...)是最后结束的( 不是 ,我再说一遍不行 ,一定要去是最后启动相同的呼叫)处理所有呼叫都完成的情况。 Using asynchronous calls, you cannot just fall through after firing up a bunch of them and do a return ; 使用异步调用,您不能在激发一堆并returnreturn you will have to put the code that you want to run after all the work is done in a callback that addresses what I called "handles" earlier. 在完成所有工作之后,您将必须将要运行的代码放在一个回调中,该回调解决了我之前所说的“句柄”。

Control-flow libraries like async.js could simplify your code, but you'll need to get your head around the notion that once your function goes async everything that follows it has to be async as well. 诸如async.js之类的控制流库可以简化您的代码,但您需要注意以下概念:一旦函数异步,其后的所有内容也必须异步。

ebohlman pretty much called it. ebohlman几乎称之为。 Right now your for loop is setting up the anonymous functions that the rename function will call once it finishes. 现在,您的for循环正在设置匿名函数,重命名函数完成后将调用该匿名函数。

As soon as these are setup, imagenesIn will return directories. 这些设置完成后,imagenesIn将返回目录。 It may contain some or none of the directories, depending on whether or not rename finished before your return. 它可能不包含某些目录,也可能不包含这些目录,具体取决于返回之前是否重命名完成。

The power of node is that it is asynchronous. 节点的力量在于它是异步的。 You could use fs.renameSync yes, and it would follow what you expect. 您可以使用fs.renameSync yes,它将遵循您的期望。 Node is not like an apache php server. 节点不像一个Apache PHP服务器。 The php server gets a request, and reserves a small slice of memory for the request. php服务器获取一个请求,并为该请求保留一小部分内存。 That's why other requests can still be processed, because they all get their own memory. 这就是为什么其他请求仍然可以处理的原因,因为它们都拥有自己的内存。 Node doesn't do this. 节点不这样做。 It runs on a single thread and if you do anything that is blocking (like synchronous IO), other requests have to wait until it's finished before they can be processed. 它运行在单个线程上,并且如果您执行任何阻塞的操作(例如同步IO),则其他请求必须等到完成后才能进行处理。

Ideally, your imagenesIn should also be asynchronous as well, taking a function as the final parameter. 理想情况下,您的imagenesIn也应该是异步的,并以函数作为最终参数。 The standard for the function usually follows function(error, data). 该功能的标准通常遵循功能(错误,数据)。 Error should be null if there was none. 如果没有错误,则错误应为null。 fs.rename follows this pattern. fs.rename遵循此模式。

Also the function that calls imagenesIn should ideally handle the server response. 同样,调用imagenesIn的函数也应该理想地处理服务器响应。 This allows the function to be used in other types of cases. 这允许该功能在其他类型的情况下使用。 What if you don't want to send that specific response on error? 如果您不想在出错时发送该特定响应怎么办? What if you don't want to send a response at all? 如果您根本不想发送回复怎么办? Right now this is a good recipe for accidentally sending headers twice (and getting an error). 现在,这是一个意外发送标头两次(并收到错误)的好方法。

If it were me, this is how I would write your function (I didn't test but should give you some direction). 如果是我,这就是我编写您的函数的方式(我没有测试,但应该给您一些指导)。

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.');
    }
}

and your code that calls it might look something like this 您的调用它的代码可能看起来像这样

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

Also, I wanted to make sure you understood the unique difference between for( ; ; ) and for(key in object). 另外,我想确保您了解for(;;)和for(key in object)之间的唯一区别。 "For in" iterates through the keys of an object. “ For in”将遍历对象的键。 This works on an array because it is essentially an object with numeric keys. 这对数组有效,因为它本质上是带有数字键的对象。 I could do this however 我可以做到这一点

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

If you did for (var i = 0; i < array.length; i++), you would only iterate through the array data. 如果您这样做(var i = 0; i <array.length; i ++),则仅迭代数组数据。 If you used for (key in array), you would also iterate through the nonNumericKey. 如果用于(数组中的键),则还需要遍历nonNumericKey。 This is why personally, I only use "for in" on objects that are not arrays. 这就是为什么我个人只对非数组对象使用“ for in”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM