2017-02-21 13 views
1

Я хочу создать простую игровую площадку со стеком MEAN, который имитирует плункер: у нас есть список файлов и текстовое поле в левой руке, а прямой просмотр справа. Обратите внимание, что файлы сохраняются во временной папке, а предварительный просмотр в реальном времени - это iframe, введенный файлами из этой временной папки.Последовательные записи файлов на сервере медленны

enter image description here

Я закодирован что-то. В интерфейсе контроллер отслеживает изменения файлов в текстовом поле; каждый раз, когда происходит изменение, вызывается render, и он отправит $http.post, чтобы сохранить новую версию всех файлов.

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]); 
     } 
    } 
} 

На заднем конце:

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); 
}); 

Мои тесты показывают, что для первой модификации, это действительно записываются в файлы на сервере. Однако для последовательных модификаций 2-е и последующее письмо могут занимать более 20 секунд КАЖДЫЙ.

Кто-нибудь знает, что замедляет работу (за исключением 1-го)?

Кроме того, следует ли мне позвонить $http.post('/writeFile', files[i]) или написать router.post('/writeFile'... в асинхронном режиме?

Edit 1:

Мне также интересно, если правильно написать запрос HTTP следующим образом (я с асинхронной функцией (т.е. HTTP POST) внутри синхронной функции (то есть, ? render) Должен ли я сделать 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]); 
     } 
    } 
} 

Когда я вижу другие запросы HTTP в моем коде, мода часто, как

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

dont 'use 'fs.writeFileSync', используйте асинхронную версию – wong2

+0

^Это. Вся идея функций \ * Sync заключается в том, что они * блокируют *. – estus

+0

Спасибо ... см. Мое обновление ... – SoftTimur

ответ

1

Возможно, вы решите реорганизовать свой код и включить следующие вещи:

1) Оберните своего наблюдателя в функцию дебюта. https://lodash.com/docs/4.17.4#debounce

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

Это предотвращает бесполезные звонки

2) Используйте writeFile вместо writeFileSync

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

Сила NodeJs в асинхронных функциях, старается избегать синхронизаций вызовов в вашем коде.

+0

Спасибо ... У меня все еще есть один вопрос, пожалуйста, см. Мое обновление ... – SoftTimur

+0

Отвечая на ваш вопрос, правильно ли написать http-запрос следующим образом ? Короткий ответ №. Пожалуйста, поднимите отдельный вопрос, и я объясню вам, как обрабатывать последовательные асинхронные вызовы. – Cassidy

+0

ОК, напишу еще один (сложный) вопрос ... – SoftTimur

Смежные вопросы