【问题标题】:How to do first n times async loops then one time function in callback way?如何先执行 n 次异步循环,然后以回调方式执行一次函数?
【发布时间】:2016-03-03 08:37:56
【问题描述】:

这不是关于如何在nodejs中做post multipart form的问题。

但是如何以回调方式执行这样的逻辑(首先执行 n 次循环(异步)然后执行一次函数(异步))?

例如,客户将发布带有普通表单字段的多部分表单:

req.files[n]:包含n张图片,需要保存到服务器本地文件系统

req.body:包含 post.title、post.content、post.user

通常情况下(php、java...),示例代码是

array savedPath = [];
// save images to local filesystem
foreach image in files
  savedPath.push(saveImageToLocal(image))
// append saved images path to post
var post = req.body;
post.images = savedPath;
Posts.insert(post)

但是在nodejs中,回调的方式,怎么写呢?

var savedPath = [];
saveImageToLocal(files[0], function(path) {
  savedPath.push(path);
  saveImageToLocal(files[1], function(path) {
    savedPath.push(path);
    //.... its n elements, how can I write it??
   var post = req.body;
   post.images = savedPath;
   Posts.insert(postfunction(err, result) {
      res.send(err, result)
    });
  });
});

或者

var savedPath = [];
for(i=0;i<n;i++) {
  savesaveImageToLocalTo(files[i], function(path) {
    savedPath.push(path);
  });
}
waitSaveToFinished() ??
var post = req.body;
post.images = savedPath;
Posts.insert(postfunction(err, result) {
  res.send(err, result)
});

如何以nodejs/callback的方式来做这些事情?

【问题讨论】:

  • 您想将值存储在一个数组中,并且每次在您的回调中检查if (myArr.length == n) { finalize(); }
  • 您(或像您一样的人)大约 10 分钟前刚刚发布了这个相同的问题。我现在找不到它,所以它可能已关闭。
  • @jfriend00 为什么要关闭它?我认为这对于 nodejs/callback 新手来说很常见也很困难。
  • 我没有关闭任何东西。我只是评论说几分钟前我刚刚看到了同样的问题。当问题写得不好时,问题就会在这里关闭。这就是网站保持更高质量水平的方式。他们关闭的原因通常在关闭原因或 cmets 中进行解释。这里的新用户有时会以一种不愉快的方式被打倒,直到他们学会如何写好问题或提供好的答案。我并不是说这很好,但它经常发生。
  • @jfriend00 谢谢。我已经尽力用我糟糕的英语详细说明了这个问题,为什么他们只是关闭它而不是要求对这个问题进行更多解释?是不是因为这个问题太傻了??

标签: javascript node.js


【解决方案1】:

协调多个异步操作的最佳方式是使用 Promise。所以,如果这是我的代码,我会更改或包装 saveImageToLocalTo()Posts.insert() 以返回承诺,然后使用承诺功能来协调它们。如果您要编写大量 node.js 代码,我建议您立即投入学习 Promise 的工作原理,并开始将它们用于所有异步行为。

要在没有承诺的情况下解决您的问题,您必须实现一个计数器并跟踪所有异步操作何时完成:

var savedPath = [];
var doneCnt = 0;
for(i=0;i<n;i++) {
  savesaveImageToLocalTo(files[i], function(path) {
    ++doneCnt;
    savedPath.push(path);
    // if all the requests have finished now, then do the next steps
    if (doneCnt === n) {
        var post = req.body;
        post.images = savedPath;
        Posts.insert(postfunction(err, result) {
            res.send(err, result)
        });
    }
  });
}

此代码看起来缺少错误处理,因为大多数异步操作都有可能出错并且可以返回错误代码。

【讨论】:

  • 非常感谢,我已经阅读了承诺,正是我想要的。
猜你喜欢
  • 1970-01-01
  • 2013-02-02
  • 2015-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多