我正试图从异步过渡到承诺,这就是我所拥有的。如果代码看起来很人为,那是因为我将其从我正在处理的内容中简化出来,以便更容易掌握。我正努力让Promise.all执行。
我注释掉了我想在promises中实现的异步代码:
var Promise = require('bluebird');
var fs = Promise.promisifyAll(require('fs-extra'));
var path = require('path');
var tar = require('tar-fs');
module.exports = Archive;
function Archive() {
var self = this;
var self.base_dir = '/bar/baz',
var self.file1 = 'foo/file1',
var self.file2 = 'foo/file2',
var self.file3 = 'foo/file3',
var self.file4 = 'foo/file4'
}
Archive.prototype.make = function(done) {
var self = this;
// async.series([
// function(next) {
// self._prepareFilesDir(next);
// },
// function(next) {
// self._copyFiles(next);
// },
// function(next) {
// self._writeArchive(next);
// }
// ], done)
self._prepareFilesDir().bind(self)
.then(self._copyFiles.bind(self))
.then(self._writeArchive.bind(self))
.catch(function(e) {
return done(e);
});
};
// ********************************
// * Private functions
// ********************************
Archive.prototype._prepareFilesDir = function() {
var self = this;
return fs.emptyDirAsync(self.base_dir);
};
Archive.prototype._copyFiles = function() {
var self = this;
var sources = {
file1: path.resolve('baz', 'file1'),
file2: path.resolve('baz', 'file2')
file3: path.resolve('baz', 'file3')
file4: path.resolve('baz', 'file4')
file5: path.resolve('baz', 'file5')
};
var destinations = {
file1: path.resolve(self.base_dir, self.file1),
file2: path.resolve(self.base_dir, self.file2),
file3: path.resolve(self.base_dir, self.file3),
file4: path.resolve(self.base_dir, self.file4),
file5: path.resolve(self.base_dir, self.file5)
};
var filters = {
qux: /^qux/,
bru: /^bru/,
blerg: /blerg$/
};
function copyFile1() {
console.log('hello world');
return fs.copyAsync(sources.file2, destinations.file1, { filter: filters.qux });
};
function copyFile2() {
return fs.copyAsync(sources.file2, destinations.file2);
};
function copyFile3() {
return fs.copyAsync(sources.file3, destinations.file3, { filter: filters.bru });
};
function copyFile4() {
return fs.copyAsync(sources.file4, destinations.file4, { filter: filters.blerg });
};
return Promise.all([
copyFile1,
copyFile2,
copyFile3,
copyFile4
]);
// async.parallel([
// copyFile1(next),
// copyFile2(next),
// copyFile3(next),
// copyFile4(next)
// ], function(err) {
// if (err) return done(err);
// done(null);
// })
};
Archive.prototype._writeArchive = function() {
var self = this;
var archive_dir_path = path.resolve(self.base_dir, '..');
var tarPromise = function() {
return new Promise(function(resolve, reject) {
tar.pack(self.files_path)
.pipe(fs.createWriteStream(archive_dir_path + '.tar'))
.on('error', reject)
.on('finish', resolve)
});
};
fs.ensureDirAsync(archive_dir_path)
.then(tarPromise);
};
我必须做错事,因为你好世界'永远不会打印。我认为这个流是正确的,但我也不太确定。我的转换基于promise-nuggets.github.io片段。
我如何做Promise.all
?我希望保留单独的功能,因为我认为这有助于更好地理解代码。
谢谢,
答案 0 :(得分:1)
我发现的错误:
make
方法中,只有在出现错误的情况下才会调用done,建议删除done
回调,只返回promise make
,您正在_prepareFilesDir().bind(self)
,因为州长bind
此时是多余的,此时应该是call/apply
。_writeArchive
中,你需要返回promise,否则它将返回undefined并假设async函数已经完成。
更新fiddle
答案 1 :(得分:0)
@ mido22修复了几个问题。还有一个问题,在Pormise.all()中,函数不应该作为引用传递,而是执行。
var Promise = require('bluebird');
var fs = Promise.promisifyAll(require('fs-extra'));
var path = require('path');
var tar = require('tar-fs');
module.exports = Archive;
function Archive() {
var self = this;
var self.base_dir = '/bar/baz',
var self.file1 = 'foo/file1',
var self.file2 = 'foo/file2',
var self.file3 = 'foo/file3',
var self.file4 = 'foo/file4'
}
Archive.prototype.make = function() { // CHANGED
var self = this;
// async.series([
// function(next) {
// self._prepareFilesDir(next);
// },
// function(next) {
// self._copyFiles(next);
// },
// function(next) {
// self._writeArchive(next);
// }
// ], done)
return self._prepareFilesDir() // CHANGED
.then(self._copyFiles.bind(self))
.then(self._writeArchive.bind(self)); // CHANGED
};
// ********************************
// * Private functions
// ********************************
Archive.prototype._prepareFilesDir = function() {
var self = this;
return fs.emptyDirAsync(self.base_dir);
};
Archive.prototype._copyFiles = function() {
var self = this;
var sources = {
file1: path.resolve('baz', 'file1'),
file2: path.resolve('baz', 'file2')
file3: path.resolve('baz', 'file3')
file4: path.resolve('baz', 'file4')
file5: path.resolve('baz', 'file5')
};
var destinations = {
file1: path.resolve(self.base_dir, self.file1),
file2: path.resolve(self.base_dir, self.file2),
file3: path.resolve(self.base_dir, self.file3),
file4: path.resolve(self.base_dir, self.file4),
file5: path.resolve(self.base_dir, self.file5)
};
var filters = {
qux: /^qux/,
bru: /^bru/,
blerg: /blerg$/
};
function copyFile1() {
console.log('hello world');
return fs.copyAsync(sources.file2, destinations.file1, { filter: filters.qux });
};
function copyFile2() {
return fs.copyAsync(sources.file2, destinations.file2);
};
function copyFile3() {
return fs.copyAsync(sources.file3, destinations.file3, { filter: filters.bru });
};
function copyFile4() {
return fs.copyAsync(sources.file4, destinations.file4, { filter: filters.blerg });
};
return Promise.all([
copyFile1(), // execute functions
copyFile2(), // idem
copyFile3(), // idem
copyFile4() // idem
]);
// async.parallel([
// copyFile1(next),
// copyFile2(next),
// copyFile3(next),
// copyFile4(next)
// ], function(err) {
// if (err) return done(err);
// done(null);
// })
};
Archive.prototype._writeArchive = function() {
var self = this;
var archive_dir_path = path.resolve(self.base_dir, '..');
var tarPromise = function() {
return new Promise(function(resolve, reject) {
tar.pack(self.files_path)
.pipe(fs.createWriteStream(archive_dir_path + '.tar'))
.on('error', reject)
.on('finish', resolve)
});
};
return fs.ensureDirAsync(archive_dir_path)
.then(tarPromise); // CHANGED,
};