承诺不会返回对象数组

问题描述:

不定值:承诺不会返回对象数组

我使用Q管理与Node.js的承诺,我使用easyImage处理图像。

这段代码工作正常,它加载,保存,剪切tmp文件夹中的图像并将其粘贴到用户文件夹中。我唯一的问题是将最终数据保存到数据库。我得到了一个未定义值的数组中......

exports.postAccountImages = function(req, res, next) { 
    User.findById(req.user.id, function(err, user) { 
    var path = __dirname + '/../public/images/u/' + user._id + '/'; 
    var max = 800; 
    fs.exists(path, function(exists) { 
     if (!exists) fs.mkdirSync(path); 
    }); 

    var promises = []; 
    for (var key in req.files) { 
     if (req.files.hasOwnProperty(key)) { 
     (function(file) { 
      q().then(function() { 
      return promises.push(easyimg.info(file.path).then(function(image) { 
       easyimg.resize({ 
       src: file.path, 
       dst: path + file.name, 
       width: (image.width >= max) ? max : image.width, 
       height: (image.height >= max) ? max : image.height, 
       quality: 80 
       }).then(function(image) { 
       fs.remove('./tmp-uploads/' + image.name); 
       return { 
        src: image.name, 
        main: false 
       }; 
       }); 
      })); 
      }); 
     })(req.files[key]); 
     } 
    } 

    q.all(promises).then(function(result) { 
     console.log(result); // [undefined, undefined, undefined, ...] 
     // Here I should push result to the DB 
    }); 
    }); 
}; 
+2

您需要对承诺和异步回调进行一些学习。这个答案可能会帮助你:http://*.com/questions/14220321/how-to-return-the-response-from-an-ajax-call。一般来说,您必须在异步回调中“使用”异步结果,而不是其他任何地方。 – jfriend00 2014-12-03 22:27:36

+0

我确信我必须了解承诺,但是从您发布的链接中,我不太确定我应该如何处理。 它用jQuery解释了一些东西......我用Express和Node ...问题是:我怎样才能得到回报? – 2014-12-03 22:31:13

+0

我可以根据我的问题举个例子吗? – 2014-12-03 22:52:38

下面是如何做到这一点的一般概念(未经测试):

var promises = []; 
for (var key in req.files) { 
    if (req.files.hasOwnProperty(key)) { 
     (function(file) { 
      promises.push(easyimg.info(file.path).then(function(image) { 
       return easyimg.resize({ 
        src: file.path, 
        dst: path + file.name, 
        width: Math.max(image.width, 800), 
        height: Math.max(image,height, 800), 
        quality: 80 
       }).then(function(image) { 
        fs.remove('./tmp-uploads/' + image.name, function(err) { 
         if (err) { 
          // logging error, but not stopping execution 
          // since this is a non-fatal error 
          console.log("err removing temp upload: ", err); 
         } 
        }); 
        return {src: file.name, main: false}; 
       }); 
      })); 
     })(req.files[key]); 
    } 
} 
// now wait for all promises to finish 
// assumes you want to call next() no matter what when all image processing is done 
Promise.all(promises).then(function(results) { 
    // all results are in the results array here 
    // do whatever processing of the results array you want to do here 
    res.sendStatus(200); 
    next(); 
}, function() { 
    // set some status to send when there's an error 
    res.sendStatus(xxx); 
    next(); 
}); 

我纠正一些问题,并提出了一些改进:

  1. 当处理多个文件时,您的变量file被覆盖,因为您尝试在多个异步回调中使用相同的变量。我把它放到一个闭包中,因此它被分别保存到每个正在处理的图像中。这可能是使其不能处理多个图像的主要问题。

  2. 你没有在所有正确的时间呼叫next()(有时称它太多次)。

  3. 你的错误处理有多个问题,因为你不能只是返回一个异步方法来停止处理。

  4. 我决定,如果你不能删除处理应该继续而不是中止的临时文件,因为这不是一个致命的问题。

  5. 此代码使用Promise.all()在完成所有操作而不是使用手动计数器时获得回调。这也使错误处理更简单。

+0

谢谢,它帮助我管理整个过程,并且我看到我需要学习承诺,我仍然在学习,而且我从来没有面对过。 我编辑了我原来的问题,一切正常,我用Q来管理你的诺言。但就目前而言,你可以阅读我仍然有一个最终的问题q.all返回一个数组里面没有数据...该数据是我应该推到数据库的最终数据。如果你能解释这一点,我会很感激。谢谢。 – 2014-12-04 12:26:14

+0

@AyeyeBrazo - 我在'.push()'后面添加了一条必要的return语句。这对于适当返回返回值是必要的。 – jfriend00 2014-12-04 22:06:33

+0

Promise未定义。 – 2014-12-05 13:51:05