对递归函数的回调
Callback on recursive function
下面的代码用于从我们的web应用程序中获取.zip
文件。该文件是通过安全关闭另一个应用程序,然后压缩,最后发送下载来生成的。
var dl = function() {
request({
method: 'GET',
uri: 'some_url',
headers: {
'User-Agent': 'Scripted-Download'
},
encoding: null,
jar: true
}, function(err, res, body) {
if (err) throw(err)
if (res.headers['content-type'] === 'application/zip;charset=utf-8') {
process.stdout.write(''rDownloading file ..')
var id = uuid.v4()
, file = path.resolve(__dirname, '../../' + id + '.zip')
fs.writeFile(file, body, function(err) {
if (err) throw(err)
process.stdout.write(''rFile downloaded ' + id + '.zip')
process.exit(0)
})
} else {
process.stdout.write(''rAwaiting file ..')
setTimeout(dl(), 30 * 1000)
}
})
}
按预期工作。然而,我需要从另一个脚本使用它。因此,上面的代码返回下载文件的id
,然后从另一个脚本中提取.zip
,并将提取的文件放入具有相同id
的目录中。然后这些文件就可以下载了。
EDIT基本上我需要执行这个脚本,在下载时提取内容,然后在前两个步骤完成后用res.render()
加载UI。这需要用id
来完成,这样两个用户就不会创建冲突的文件。
正如评论中提到的,承诺应该使这变得容易。首先承诺你需要的异步功能:
function makeRequest(parameters) {
return new Promise(function (resolve, reject) {
request(parameters, function (err, res, body) {
if (err) { reject (err); }
else { resolve({ res: res, body: body }); }
});
});
}
function writeFile(file, body) {
return new Promise(function (resolve, reject) {
fs.writeFile(file, body, function(err) {
if (err) { reject(err); }
else { resolve(); }
});
});
}
function timeout(duration) {
return new Promise(function (resolve) {
setTimeout(resolve, duration);
});
}
那就用它们。
var dl = function () {
return makeRequest({
method: 'GET',
uri: 'some_url',
headers: {
'User-Agent': 'Scripted-Download'
},
encoding: null,
jar: true
}).then(function (result) {
if (result.res.headers['content-type'] === 'application/zip;charset=utf-8') {
process.stdout.write(''rDownloading file ..')
var id = uuid.v4()
, file = path.resolve(__dirname, '../../' + id + '.zip');
return writeFile(file, result.body)
.then(function () { return id; });
} else {
process.stdout.write(''rAwaiting file ..');
return timeout(30 * 1000).then(dl);
}
});
}
dl().then(function (id) { process.stdout.write(''rid is: ' + id); });
您可以使用async.
等异步实用程序库。您正在寻找的图案似乎是瀑布图案。这将允许您将所需的数据从一个任务传递到另一个任务。
function requestFile(cb){
request({
method: 'GET',
uri: 'some_url',
headers: {
'User-Agent': 'Scripted-Download'
},
encoding: null,
jar: true
}, function(err, res, body) {
if (err) throw(err)
if (res.headers['content-type'] === 'application/zip;charset=utf-8') {
process.stdout.write(''rDownloading file ..');
cb(null, body);
}
else{
process.stdout.write(''rAwaiting file ..');
setTimeout(requestFile, 30 * 1000)
}
});
}
function saveFile(body, cb){
var id = uuid.v4()
, file = path.resolve(__dirname, '../../' + id + '.zip')
fs.writeFile(file, body, function(err) {
if (err) throw(err)
process.stdout.write(''rFile downloaded ' + id + '.zip');
cb(null, id);
})
}
function render(id, cb) {
//do what ever you need with your id
cb();
}
async.waterfall([
requestFile,
saveFile,
render
], function(err){
});
顺便说一句,我建议您直接将数据从服务器流式传输到磁盘,而不是将其全部收集到缓冲区中然后保存。
您可以在请求对象上创建data
侦听器,然后将它们直接流式传输到磁盘,或者甚至只是使用request.pipe(file)
的例子:
function streamFile(){
var id = uuid.v4()
, file = path.resolve(__dirname, '../../' + id + '.zip');
var stream = fs.createWriteStream(file);
stream.on('error', function(err){
throw err;
}).on('close', function(){
process.stdout.write(''rFile downloaded ' + id + '.zip')
});
request({
method: 'GET',
uri: 'some_url',
headers: {
'User-Agent': 'Scripted-Download'
},
encoding: null,
jar: true
}).on('error', function(err) {
throw(err)
}).on('response', function(res){
if (res.headers['content-type'] === 'application/zip;charset=utf-8') {
process.stdout.write(''rDownloading file ..');
cb(null, body);
}
else{
process.stdout.write(''rAwaiting file ..');
res.destroy();
setTimeout(streamFile, 30 * 1000)
}
}).pipe(stream);
}
相关文章:
- 递归函数中断
- 将jQuery对象传递到setTimeout递归函数中
- TypeError:执行回调时,回调不是函数
- 对象与递归函数的比较
- 在 Angular 指令中,如何进行回调,其中函数名称位于父范围的变量中
- 循环内部的递归函数未按预期工作
- 递归函数返回不正确
- 对回调使用命名函数
- 从多线程C++插件回调NodeJS Javascript函数
- 递归函数编程困境
- 给定一个带有数字的数组,我如何编写一个递归函数,当 2 个元素加起来为一个目标时,它会在数组中查找索引
- 返回不会退出 javascript 中的递归函数
- jquery递归函数转换为非递归函数
- AngularJS,promise带有递归函数
- 如何停止此递归函数
- 如何将下面的递归函数转换为纯函数
- 使用递归函数按顺序执行多个 ajax 请求,并在所有请求完成后执行回调函数
- 在递归函数中不能调用回调函数
- 对递归函数的回调
- Javascript递归函数回调如何识别何时所有函数调用已经结束