2014-10-16 3 views
3

У меня есть задание написать части данных в отдельных файлах:Multiple WriteFile в NodeJS

 fs.writeFile('content/a.json', JSON.stringify(content.a, null, 4), function(err) { 
      if(err) { 
       console.log(err); 
      } else { 
       console.log('a.json was updated.'); 
      } 
     }); 
     fs.writeFile('content/b.json', JSON.stringify(content.b, null, 4), function(err) { 
      if(err) { 
       console.log(err); 
      } else { 
       console.log('b.json was updated.'); 
      } 
     }); 
     fs.writeFile('content/c.json', JSON.stringify(content.c, null, 4), function(err) { 
      if(err) { 
       console.log(err); 
      } else { 
       console.log('c.json was updated.'); 
      } 
     }); 
     fs.writeFile('content/d.json', JSON.stringify(content.d, null, 4), function(err) { 
      if(err) { 
       console.log(err); 
      } else { 
       console.log('d.json was updated.'); 
      } 
     }); 

Но теперь у меня есть 4 различных обратных вызовов, так что я не могу получить в тот момент, когда все четыре задачи имеют был закончен. Возможно ли параллельное 4 вызова writeFile и получить только 1 обратный вызов, который будет вызываться, когда было создано 4 файла?

P.S.

Конечно, я могу сделать что-л, как:

fs.writeFile('a.json', data, function(err) { 
    fs.writeFile('b.json', data, function(err) { 
    .... 
    callback(); 
    } 
} 

Просто интересно, есть ли другой способ сделать это. Благодарю.

+0

посмотреть модуль НПМ с именем 'async'. Вы также можете использовать встроенный модуль 'prom', но асинхронно было бы легче понять. –

+0

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

+0

Спасибо всем, ребята, асинхронный модуль есть что-то, что я ищу. –

ответ

8

Вы можете использовать модуль async. Она также помогает очистке кода:

var async = require('async'); 

async.each(['a', 'b', 'c', 'd'], function (file, callback) { 

    fs.writeFile('content/' + file + '.json', JSON.stringify(content[file], null, 4), function (err) { 
     if (err) { 
      console.log(err); 
     } 
     else { 
      console.log(file + '.json was updated.'); 
     } 

     callback(); 
    }); 

}, function (err) { 

    if (err) { 
     // One of the iterations produced an error. 
     // All processing will now stop. 
     console.log('A file failed to process'); 
    } 
    else { 
     console.log('All files have been processed successfully'); 
    } 
}); 
+0

Я немного запутался в обратном вызове() после инструкции if/else. В чем его цель? – Winnemucca

3

Да, вы должны использовать async, параллельный метод выглядит следующим образом:

async.parallel([ 
    function(callback){ 
     fs.writeFile('content/a.json', JSON.stringify(content.a, null, 4), callback); 
    }, 
    function(callback){ 
     fs.writeFile('content/b.json', JSON.stringify(content.b, null, 4), callback); 
    }, 
    function(callback){ 
     fs.writeFile('content/c.json', JSON.stringify(content.c, null, 4), callback); 
    }, 
    function(callback){ 
     fs.writeFile('content/d.json', JSON.stringify(content.d, null, 4), callback); 
    } 
], 
function(err, results){ 
    // all done 
}); 
1

уборщик способ сделать это .. было бы сделать это async.map

var async = require('async'); 

var arr = [{'filename':'content/a.json', 'content':content.a},{'filename':'content/b.json', 'content':content.b}]; 
async.map(arr, getInfo, function (e, r) { 
    console.log(r); 
}); 

function getInfo(obj, callback) { 
    fs.writeFile(obj.filename, JSON.stringify(obj.content, null, 4), callback); 
} 
1

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

var Promise = require('bluebird'); 
var fs = Promise.promisifyAll(require('fs')); 

var promises = ["a", "b", "c", "d"].map(function(val) { 
    return fs.writeFileAsync('content/' + val + ".json", JSON.stringify(content[val], null, 4)); 
}); 

Promise.all(promises).then(function() { 
    // all writes are done here 
}).catch(function(err) { 
    // error here 
}); 
0

С ES6 вы можете сделать:

function writeFile(file, index) { 
 
    return new Promise((resolve, reject) => { 
 
     let fileUrl = `content/${index}.json`; 
 
     fs.writeFile(fileUrl, JSON.stringify(file, null, 4), 
 
      (err) => { 
 
       if (err) 
 
        reject (err); 
 
       else 
 
        resolve(fileUrl) 
 
      }); 
 
    }); 
 
} 
 
let files = Object.keys(content).map(key => writeFile(content[key])); 
 
Promise.all(files).then(values => {/*Files Urls*/}, err => {/*Some Error*/});