问题描述
我试图内的Node.js写一个的Robocopy / MIR之类的功能似乎并不能换行我围绕如何才能正确地执行多个异步函数头。
一些背景资料:
- 剧本是在Windows上运行,所以,我需要找到某种方式来拷贝文件,同时保留修改时间和接收进度通知。
- 要解决这个问题,我继续和放大器;在.NET中写道:我的复制功能(与Edge.js调用它) - 此复制功能只需调用回节点功能的报告文件拷贝进度。这幅作品完美。
要具备文件复制顺序,我首先想到的是做类似如下:
Object.keys(filesToCopy).forEach(功能(键){
VAR递延= q.defer();
VAR有效载荷= {
SOURCEPATH:键,
destPath:filesToCopy [关键],
progressCallback:progressCallback
}; 的console.log('复制%s ...',SOURCEPATH);
// Edge.js这里所说的
copyFile(有效载荷,deferred.makeNodeResolver()); deferred.promise.then(功能(结果){
的console.log('%s的完成。,结果);
},功能(错误){
console.error('错误:',err.message);
}); promises.push(deferred.promise);
});
不幸的是,这(如预期)开始只要.NET函数被调用每一个拷贝文件,因此,我得到一次给我像输出进度所有文件通知:
1%
2%
1%
2%
3%
3%
好像我需要一种方法来排队的工作射击它关闭全部一次,每个项目在未来收益之前完成之前完成。当所有项目都完成我需要得到通知。解决的办法似乎很简单,但继续担任每次我试图角带有另一个问题逃避我。任何帮助将大大AP preciated,谢谢!
编辑:正如我在评论说,BERGI提供了答案被利用而函数没有的实际上是返回一个承诺,而我Edge.js功能没有。我能够利用一个数组而不是对象的 filesToCopy
,然后做这样的事情,所以先解决我的问题:
返回filesToCopy.reduce(函数(preV,CURR){
返回prev.then(函数(){
VAR递延= q.defer();
copyFile(CURR,功能(错了,结果){
deferred.resolve(结果);
的console.log(已完成%s'的,结果);
});
返回deferred.promise;
})
},Q());
这可能不是这样做的最佳方式,但它适合我的用途。
也许这样的事情会做的伎俩:
变量$ J =功能(VAL,空间){\r
返回JSON.stringify(VAL,空,太空||'')\r
}\r
VAR日志=功能(VAL){\r
document.body.insertAdjacentHTML('beforeend','< DIV>< pre>'+ VAL +'< / DIV>< / pre>')\r
}\r
\r
\r
\r
var中的文件='12345'.split('')。映射(函数(五){\r
返回{\r
名称:'_文件'+ V +'.js文件',\r
载:函数(){\r
VAR CUR =这一点;\r
VAR亲=新的承诺(函数(解析,拒绝){\r
\r
日志('装:'+ cur.name);\r
\r
//我们simualate加载的东西\r
的setTimeout(函数(){\r
解决(cur.name);\r
},1 * 1000);\r
\r
})。然后(功能(VAL){\r
\r
//一旦装\r
日志('装:'+ VAL);\r
返回VAL;\r
\r
});\r
\r
返回亲;\r
\r
}\r
};\r
});\r
\r
\r
files.reduce(函数(T,V){\r
\r
t.promise = t.promise.then(函数(){\r
返回v.load();\r
});\r
\r
返回吨;\r
},{\r
承诺:Promise.resolve(1)\r
});
\r
I am attempting to write a "robocopy /mir" like function within Node.js and cannot seem to wrap my head around how to properly execute several async functions in order.
Some background:
- The script is run on Windows, therefore, I needed to find some way to copy files while retaining modification time AND receiving progress notifications.
- To solve this problem, I went ahead & wrote my copy function in .NET (calling it with Edge.js)--this copy function simply calls back to a Node function reporting file copy progress. This piece works flawlessly.
To have the files copy in order, my first thought was to do something like follows:
Object.keys(filesToCopy).forEach(function(key) {
var deferred = q.defer();
var payload = {
sourcePath: key,
destPath: filesToCopy[key],
progressCallback: progressCallback
};
console.log('Copying %s...', sourcePath);
// Edge.js called here
copyFile(payload, deferred.makeNodeResolver());
deferred.promise.then(function(result) {
console.log('%s complete.', result);
}, function(err) {
console.error('Error: ', err.message);
});
promises.push(deferred.promise);
});
Unfortunately, this (as expected) begins copying each files as soon as the .NET function is called, therefore, I get progress notifications for all files at once giving me output like:
1%
2%
1%
2%
3%
3%
It seems like I need a way to queue up the work to be done before firing it off all at once, with each item completing before the next proceeds. When all items are complete I would need to be notified. The solution seems simple enough but continues to elude me as every angle I try comes with another issue. Any help would be greatly appreciated, thank you!
EDIT: As stated in my comment, the answer Bergi provided was utilizing a function which did in fact return a promise whilst my Edge.js function did not. I was able to resolve my issue first by utilizing an array instead of an object for filesToCopy
, then doing something like so:
return filesToCopy.reduce(function(prev, curr) {
return prev.then(function() {
var deferred = q.defer();
copyFile(curr, function(err, result) {
deferred.resolve(result);
console.log('Completed %s', result);
});
return deferred.promise;
})
}, q());
This may not be the best way to do this but it works for my uses.
Maybe something like that will do the trick :
var $j = function(val, space) {
return JSON.stringify(val, null, space || '')
}
var log = function(val) {
document.body.insertAdjacentHTML('beforeend', '<div><pre>' + val + '</div></pre>')
}
var files = '12345'.split('').map(function(v) {
return {
name: 'file_' + v + '.js',
load: function() {
var cur = this;
var pro = new Promise(function(resolve, reject) {
log('loading : ' + cur.name);
// we simualate the loading stuff
setTimeout(function() {
resolve(cur.name);
}, 1 * 1000);
}).then( function( val ) {
// once loaded
log('loaded : ' + val);
return val;
});
return pro;
}
};
});
files.reduce(function(t, v) {
t.promise = t.promise.then(function(){
return v.load();
});
return t;
}, {
promise: Promise.resolve(1)
});
这篇关于我怎样才能正确地调用异步函数的列表,以便?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!