2016-12-05 204 views
0

我有一个NodeJS脚本为用户调用API,为每个用户获取多个数据并将其全部写入本地文件。我试图在将所有数据写入文件后将该文件上传到服务器。问题在于应该上传文件的代码在文件完全填充之前执行。代码写在下面。我无法弄清楚如何保证等待第一个功能的完成。NodeJS承诺等待完成

var fs = require('fs'); 
var server = require('some-server'); 
var service = require('./some-service.js'); 
var moment = require('moment-timezone'); 
var csvWriter = require('csv-write-stream'); 
var writer = csvWriter({ 
sendHeaders: false 
}); 

var users = require('./some-users') 
writer.pipe(fs.createWriteStream('myFile' + '.txt')) 

service.login().then(function (response) { 

users.forEach(function (user) { 

    service.getSpecificUser(user).then(function (response) { 

     var myUser = JSON.parse(response) 
     service.getDataForUser(user.Info).then(function (response) { 
      var userData = JSON.parse(response); 
      if (userData.IsValid) { 
       userData.AdditionalInfo.forEach(function (additionalInfo) { 
        service.getAdditionalInfo(myUser.Info, userData.data).then(function (response) { 

         //Collect additional info and combine final results to write into file 
         // write to output csv file 
         writer.write({ 
          //write information that is of interest 
         }) 

        }, function (error) { 
         console.log('error getting additional data', error); 
        }) 
       } 
       ) 
      } 
     }, function (error) { 
      console.log('error getting user data', error) 
     }) 
    }, function (error) { 
     console.log('error', myUser, error) 
    }) 
}); 
}, function (error) { 
console.log('not logged', response); 
}).then(function() { 
//perform uploading to server 
var fpath = 'path of file that contains downloaded data' 
console.log("Trying to upload to file: " +fpath) 
service.UploadFile(fpath, function (error, result, response) { 
    if (!error) { 
     console.log("Uploaded " + name); 
    } 
    else { 
     console.log(error); 
    } 

}) 
}) 

任何帮助,将不胜感激。

+0

'javascript'的哪个部分应该最后调用? 'writer.write()'有回调,还是返回'Promise'? – guest271314

+0

@ guest271314最后一个功能需要将文件上传到服务器,并且需要最后调用 – alminh

+0

[您无法在承诺中使用'.forEach'](http://stackoverflow.com/q/37576685/1048572)。 – Bergi

回答

1

您可以用Promise.all()Array.prototytpe.map()替代.forEach()csv-write-steam的文档似乎使用.end()最后完成调用.write().then()

service.login().then(function(response) { 
    return Promise.all(users.map(function(user) { 
     return service.getSpecificUser(user).then(function(response) { 
     var myUser = JSON.parse(response) 
     return service.getDataForUser(user.Info).then(function(response) { 
      var userData = JSON.parse(response); 
      if (userData.IsValid) { 
      return Promise.all(userData.AdditionalInfo.map(function(additionalInfo) { 
       return service.getAdditionalInfo(myUser.Info, userData.data).then(function(response) { 
       //Collect additional info and combine final results to write into file 
       // write to output csv file 
       writer.write({ 
        //write information that is of interest 
       }); 
       }) 
      })) 
      } 
     }) 
     }) 
    })); 
    }) 
    .then(function() { 
    writer.end(); 
    //perform uploading to server 
    var fpath = 'path of file that contains downloaded data' 
    console.log("Trying to upload to file: " + fpath) 
    service.UploadFile(fpath, function(error, result, response) { 
     if (!error) { 
     console.log("Uploaded " + name); 
     } else { 
     console.log(error); 
     } 

    }) 
    }) 
    .catch(function(e) { 
    console.log(e) 
    }) 
+0

你不能在那里调用'writer.end()'。写入过程是同步的,你不需要等待任何东西。 'writer.end()'不返回承诺。即使这样做,你也不需要'Promise.resolve'。 – Bergi

+0

为什么在发生错误时仍然上传文件?你应该把'.catch'移到最后。 – Bergi

+0

@Bergi还没有尝试过'csv-write-stream'。正准备阅读剧本本身。 '.end()'不需要被调用?移动'.catch()'链接到'.then()' – guest271314