Consecutive writings to files in the server are slow

…衆ロ難τιáo~ 提交于 2019-12-24 12:29:59

问题


I want to build a simple playground with MEAN stack that mimics plunker: we have a list of files and a textarea on the left hand, and a live preview on the right hand. Note that the files are saved in a temporary folder, and the live preview is an iframe injected by the files from that temporary folder.

I have coded something. In the front-end, the controller watches on modifications of files in the textarea; each time there is a change, render will be called and it will send a $http.post to save the new version of all the files.

app.controller('Ctrl', ['$scope', 'codeService', function ($scope, codeService) {
    ...
    $scope.$watch('files', function () {
        codeService.render($scope.files)
    }, true);
}]);

app.service('codeService', ['$http', function ($http) {
    this.render = function (files) {
        ...
        var arrayLength = files.length;
        for (var i = 0; i < arrayLength; i++) {
            $http.post('/writeFile', files[i]);
        }
    }
}

In the back-end:

router.post('/writeFile', function (req, res, next) {
    console.log("router.post /writeFile");
    var file = req.body;
    var fs = require('fs');
    fs.writeFileSync("public/tmp/" + file.name, file.body);
});

My tests show that, for the first modification, it is indeed written to the files in the server. However, for consecutive modifications, the 2nd and following writing may take more than 20 seconds EACH.

Does anyone know what slows the writings (except for the 1st one)?

Additionally, should I call $http.post('/writeFile', files[i]) or write router.post('/writeFile'... in an asynchronous way?

Edit 1:

I am also wondering if it is correct to write the http request in the following way (am I having an asynchronous function (ie, http post) inside a synchronous function (ie, render)? Should I make render asynchonous?):

app.service('codeService', ['$http', function ($http) {
    this.render = function (files) {
        ...
        var arrayLength = files.length;
        for (var i = 0; i < arrayLength; i++) {
            $http.post('/writeFile', files[i]);
        }
    }
}

When I see other http requests in my code, the fashion is often like

o.create = function (post) {
    return $http.post('/posts', post, {
        headers: { Authorization: 'Bearer ' + auth.getToken() }
    }).success(function (data) {
        o.posts.push(data)
    });
};

回答1:


Your could try to refactor your code and include following things:

1) Wrap your watcher into debounce function.https://lodash.com/docs/4.17.4#debounce

$scope.$watch('files', _.debounce(function () {
        codeService.render($scope.files)
    }, 1000), true);

It prevents useless calls

2)Use writeFile instead of writeFileSync

fs.writeFile("public/tmp/" + file.name, file.body, (err) => {
  if (err) throw err;
  console.log('It\'s saved!');
});

The power of NodeJs in async functions, try to avoid sync calls in your code.



来源:https://stackoverflow.com/questions/42364694/consecutive-writings-to-files-in-the-server-are-slow

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!