Node.js处理连续的异步操作

时间:2018-01-02 20:51:09

标签: javascript node.js

我试图编写一个异步函数来创建一些带有node.js的用户目录。

我希望使用包含操作状态的响应来执行回调,以便以后处理。但是对象不是从for循环和第二个mkdir中记录的。即使正确创建了所有目录,子目录名也会记录为相同的东西吗?

我一直在寻找如何解决这个问题,我认为由于关闭而需要IIFE?我现在完全迷失了如何解决它。任何人都可以帮我指出正确的方向吗?

这是我的代码:



const fs = require('fs');
const path = require('path');

var showSettings = {
  "userDirectories": ["shows", "uploads", "backups", "logs"],
  "showsFolder": "shows"
};

var Files = function() {};


Files.prototype.makeUserDirectories = (username, callback) => {
  let directory = (path.join(__dirname, "../users", username));
  let response = {};
  fs.mkdir(directory, err => {
    if (err) {
      response.status = "ERROR";
      response.error = err;
      console.log('failed to create directory', err);
    } else {
      console.log(`creating directory ${directory} succeeded`);
      let subdirectory = "";
      for (let i = 0; i < showSettings.userDirectories.length; i++) {
        subdirectory = (path.join(__dirname, "../users", username, showSettings.userDirectories[i]));
        fs.mkdir(subdirectory, err => {
          if (err) {
            response.status = "ERROR";
            response.error = err;
            console.log('error creating subdirectory', err);
          } else {
            response.status = "OK";
            console.log(`creating directory ${subdirectory} succeeded`);
          };

        });
      }
      console.log(response);
    }
    if (callback && typeof(callback) === "function") {
      console.log(response);
      callback(response);
    }
  });
};

testFiles.makeUserDirectories("mr.test@somedomain.com", function(data) {
  console.log("in callback function");
  console.log(data);
});
&#13;
&#13;
&#13;

我的问题是返回的回调响应对象是空的。 我认为它与for循环和IIFE有关但我不完全确定如何做到这一点,或者是否有更好的方法来实现我想做的事情?

非常感谢!

1 个答案:

答案 0 :(得分:0)

您的问题是您在异步操作完成之前尝试执行回调。异步操作可能非常复杂,并且有许多库可以使事情变得更简单,许多库都基于Promises的概念。这些对象允许您将多个操作链接在一起,但成本更高。我强烈建议使用Promises来产生更直观的功能:

const fs = require('fs');
const path = require('path');

var showSettings = {
    "userDirectories": ["shows", "uploads", "backups", "logs"],
    "showsFolder": "shows"
};

var Files = function() {};

function mkdir(path) {
    return new Promise((resolve, reject) => {
        fs.mkdir(path, (err) => {
            if(err) {
                reject(err);
            } else {
                resolve("OK");
            }
        })
    });
}

Files.prototype.makeUserDirectories = (username, callback) => {
    let directory = (path.join(__dirname, "../users", username));

    return mkdir(directory).then(() => {
        console.log(`creating directory ${directory} succeeded`);
        let subdirectory = "";
        const operations = [];
        for (let i = 0; i < showSettings.userDirectories.length; i++) {
            subdirectory = (path.join(__dirname, "../users", username, showSettings.userDirectories[i]));
            operations.push(mkdir(subdirectory));
        }

        return Promise.all(operations);
    }).then((status) => { // this will not be called until all operations complete
        console.log({status});
        if (callback && typeof(callback) === "function") {
            callback({status});
        }
    }).catch((error) => { // this will be called if an error is encountered at any point
        callback({status: 'ERROR', error});
    })
};

var testFiles = new Files();

testFiles.makeUserDirectories("mr.test@somedomain.com", function(data) {
    console.log("in callback function");
    console.log(data);
});

编辑:更新了更清洁的实施。