首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Node.js不等待嵌套的内部函数调用执行

Node.js不等待嵌套的内部函数调用执行
EN

Stack Overflow用户
提问于 2018-01-08 02:55:30
回答 1查看 302关注 0票数 0

诚然,我是node的新手,但它看起来应该工作得很好。我使用多方来解析一个表单,它返回一个数组。然后,我使用for each来遍历数组。但是,for each并不等待内部代码执行。不过,我有点困惑,为什么它不是。

代码语言:javascript
复制
var return_GROBID =  function(req, res, next) {
  var form = new multiparty.Form();

  var response_array = [];
  form.parse(req, function(err, fields, files) {

    files.PDFs.forEach(function (element, index, array) {
      fs.readFile(element.path, function (err, data) {
        var newPath = __dirname + "/../public/PDFs/" + element.originalFilename;
        fs.writeFile(newPath, data, function (err) {
          if(err) {
            res.send(err);
          }
          GROBIDrequest.GROBID2js(newPath, function(response) {
            response_array.push(response);
            if (response_array.length == array.length) {
                res.locals.body = response_array;
                next();
            }
          });
        });
      });
    });
 });
}

如果有人能给我一些正确的方法来做这件事,那就太好了。

编辑:谜团仍在继续。我在另一台机器上运行了这段代码,它工作了。怎么一回事?为什么一台机器和另一台机器不一致?

EN

回答 1

Stack Overflow用户

发布于 2018-01-08 03:16:44

我猜PDFs.forEach是你在叫the built-in forEach function,对吗?

在Javascript中,许多事情都是异步的-这意味着给定:

代码语言:javascript
复制
linea();
lineb();

lineb可能会在linea完成它启动的任何操作之前执行(因为在异步编程中,我们不会一直等到网络请求返回)。

这与其他编程语言不同:即使linea可能需要一些时间(比如发出网络请求),大多数语言也会“阻塞”,直到linea完成。(这称为同步编程)。

完成前言后,回到您最初的问题:

所以forEach是一个同步函数。如果你像下面这样重写你的代码,它将会工作(但没有用):

代码语言:javascript
复制
 PDFs.forEach(function (element, index, array) {
   console.log(element.path)
 }

(console.log是Javascript中一种罕见的同步方法)。

但是在你的 forEach循环中,你有fs.readFile。注意到最后一个参数了吗,一个函数?当操作完成时,节点将回调该函数(回调)。

正如观察到的,您的代码当前将命中该fs.readFile,说“好的,下一件事”,然后继续循环中的下一项。

解决这个问题的一种方法是使用async库,而对代码的更改最少。

代码语言:javascript
复制
async.forEachOf(PDFs, function(value, key, everythingAllDoneCallback) {

 GROBIDrequest.GROBID2js(newPath, function(response) {
        response_array.push(response);
        if (response_array.length = array.length) {
          ...
        }

        everythingAllDoneCallback(null)

} );

使用这段代码,您将完成所有的异步工作,然后在可以安全地移动到列表中的下一项时触发回调。

像这样的节点和回调是一个非常常见的Node模式,它应该在Node的初学者材料中有很好的介绍。但它是最.Node开发中的意外概念。

我在这上面找到的一个资源是(从一组课程中的一个)关于NodeJS For Beginners: Callbacks。这一点,再加上阻塞(同步)和非阻塞(异步)函数,希望这个答案能提供一些启示:)

票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48140506

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档