2016-12-05 247 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