promise with loop and file read in nodejs

2019-02-25 20:03发布

问题:

I looked at lot of example but couldn't achieve it..so need help..

Problem..

  1. the content from loop should be passed to execute one by one.
  2. each loop iteration contains a file read and database save operation along with few other object properties that need to be assigned.

I have created example here..

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

how to run:

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

method : POST

content-type : multipart/form-data

upload more than one file with name.

..

the final expected promise is

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

- saved to db.

currently i am getting different content from file..but other files content are not filled and is undefined.

Regards Moyeen

回答1:

The technique you're looking for is thenable chaining

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

Basically, we tell each operation to happen after the previous one has finished by chaining them and returning which causes a wait on the asynchronous value.

As a byproduct you can later use

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

The handler will run when all the promises are done.



回答2:

I have updated the code with Q.all as the mentioned p.then will execute only once.

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

the question is how to use q.npost if i have mongoose model files and want to save...?