обещание с циклом и чтением файла в nodejs

Я просмотрел множество примеров, но не смог этого добиться... поэтому нужна помощь..

Проблема...

  1. содержимое из цикла должно быть передано для выполнения по одному.
  2. каждая итерация цикла содержит операцию чтения файла и сохранения базы данных, а также несколько других свойств объекта, которые необходимо назначить.

Я создал пример здесь..

http://runnable.com/VI1efZDJvlQ75mlW/api-promise-loop-for-node-js-and-hello-world

как запустить:

API: http://web-91b5a8f5-67af-4ffd-9a32-54a50b10fce3.runnable.com/api/upload

метод: ПОСТ

тип содержимого: multipart/form-data

загрузить более одного файла с именем.

..

последнее ожидаемое обещание

files.name = "name of file"
files.content
files.content-type
files.size

- сохраняется в бд.

в настоящее время я получаю другое содержимое из файла ... но содержимое других файлов не заполнено и не определено.

С уважением Мойен


person procoder    schedule 14.12.2014    source источник
comment
Не могли бы вы опубликовать соответствующий код в своем вопросе?   -  person Bergi    schedule 14.12.2014
comment
@Bergi код в ссылке ..   -  person procoder    schedule 14.12.2014
comment
Что ж, проблема именно в этом. См. также эту запись часто задаваемых вопросов.   -  person Bergi    schedule 14.12.2014
comment
И теперь, конечно, runnable был выкуплен, и все, что находится по вашему URL-адресу, имеет размер 1 ГБ и не похоже на код javascript. Показательный пример того, что говорил @Bergi!   -  person NH.    schedule 03.05.2018


Ответы (2)


Техника, которую вы ищете, - это затемняемая цепочка

var p= Q();
Object.keys(files).forEach(function(key){
  p = p.then(function(){ // chain the next one
    return Q.nfcall(fs.readFile, files[key].path, "binary", i). // readfile
      then(function (content) { // process content and save
        files.filename =  files[key].name;
        files.path = files[key].path;
        files.content_type = files[key].type;
        files.size = files[key].size;
        console.log(files.filename);
        files.content = binaryToBase64(content);
        return Q.npost(art.save, art); // wait for save, update as needed
    }));
  });
});

По сути, мы сообщаем, что каждая операция должна выполняться после завершения предыдущей, объединяя их в цепочку и returning, что вызывает ожидание асинхронного значения.

В качестве побочного продукта вы можете позже использовать

p.then(function(last){
    // all done, access last here
});

Обработчик запустится, когда все промисы будут выполнены.

person Benjamin Gruenbaum    schedule 14.12.2014
comment
Почему бы не использовать reduce? - person Bergi; 14.12.2014
comment
@Bergi обратите внимание, что files - это объект, и я повторяю здесь его ключи, поэтому редактирование неверно. Я бы использовал .reduce в своем собственном коде, но обычно я нахожу, что люди намного меньше понимают его в переполнении стека, и заставлять их изучать две вещи одновременно (обещания и сокращения) звучит как излишество. - person Benjamin Gruenbaum; 14.12.2014
comment
я не могу проголосовать, так как у меня нет репутации для голосования .. :( - person procoder; 14.12.2014
comment
@Bergi Не беспокойся об этом, я делал это с тобой по крайней мере один / два раза раньше: P - person Benjamin Gruenbaum; 14.12.2014

Я обновил код с помощью Q.all, так как упомянутый p.then будет выполняться только один раз.

http://runnable.com/VI1efZDJvlQ75mlW/api-promise-loop-for-node-js-and-hello-world

 form.parse(req, function(err, fields, files) {
    var p = Q();
    Object.keys(files).forEach(function (key) {
        promises.push(p.then(function () { // chain the next one
            return Q.nfcall(fs.readFile, files[key].path, "binary"). // readfile
                then(function (content) { // process content and save
                   file = {};
                    file.filename = files[key].name;
                    file.path = files[key].path;
                    file.content_type = files[key].type;
                    file.size = files[key].size;
                    console.log(files[key].name);
                    file.content = binaryToBase64(content);
                    filesarr.push(file);
                   // Q.npost(art.save, art); // wait for save, update as needed
                })
        }));

        Q.all(promises);
    });
});

вопрос в том, как использовать q.npost, если у меня есть файлы модели мангуста и я хочу сохранить...?

person procoder    schedule 14.12.2014
comment
Проверьте мой ответ с return из npost - person Benjamin Gruenbaum; 14.12.2014
comment
@BenjaminGruenbaum Я пробовал этот возврат ... но он не публиковался ... просто выводился в журналах ... - person procoder; 14.12.2014
comment
@BenjaminGruenbaum Я сделал следующие изменения, которые он обновил, чем .. Q.npost (файлы, сохранить); // ждем сохранения, обновляем при необходимости - person procoder; 14.12.2014