Javascript 使用Promise保存多个文件
我有一个节点URL(使用Express创建),可用于下载地址的静态图像。因此,调用应用程序调用/download url并使用json传递多个地址,然后下载服务将调用Google Maps并在节点服务器上保存每个addrese的静态图像(然后它会将其发送回调用应用程序,但出于这个问题的目的,我只对在节点服务器中保存图像感兴趣) 最初,我们只对保存地址的卫星视图感兴趣,所以我编写了这段代码Javascript 使用Promise保存多个文件,javascript,node.js,express,promise,Javascript,Node.js,Express,Promise,我有一个节点URL(使用Express创建),可用于下载地址的静态图像。因此,调用应用程序调用/download url并使用json传递多个地址,然后下载服务将调用Google Maps并在节点服务器上保存每个addrese的静态图像(然后它会将其发送回调用应用程序,但出于这个问题的目的,我只对在节点服务器中保存图像感兴趣) 最初,我们只对保存地址的卫星视图感兴趣,所以我编写了这段代码 var request = require('request'); function saveMap(add
var request = require('request');
function saveMap(addressJson) {
return Promise.all(
//iterate over address json, get each address, call the Google Maps URL and save it.
addressJson.map(function(item) {
return new Promise(function (resolve, reject) {
var mapUrl = 'http://maps.googleapis.com/maps/api/staticmap?maptype=roadmap&markers=size:mid|color:red|' + item.address;
request(mapUrl)
.pipe(fs.createWriteStream('/temp/' + item.id + '.jpg'))
.on('finish', function () {
resolve("Promise resolved");
}).on('error', function (error) {
reject('Error in creating map', error);
})
});
})
)
}
保存每个地址的承诺被包装在Promise.all(..)中,因为我想在所有地图下载完成后返回saveMap()(这样我就可以压缩它们并发送到调用的应用程序,所以需要确保所有内容都已下载)
现在,我们需要扩展这个函数来包括卫星地图。我希望,在相同的json迭代中,我可以有另一个承诺,下载卫星地图。类似这样的东西
function saveMap(addressJson) {
return Promise.all(
//iterate over address json, get each address, call the Google Maps URL and save it.
addressJson.map(function(item) {
return new Promise(function (resolve, reject) {
var mapUrl = 'http://maps.googleapis.com/maps/api/staticmap?maptype=roadmap|' + item.address;
request(mapUrl)
.pipe(fs.createWriteStream('/temp/r/' + item.id + '.jpg'))
.on('finish', function () {
resolve("Promise resolved");
}).on('error', function (error) {
reject('Error in creating map', error);
})
});
return new Promise(function (resolve, reject) {
var mapUrl2 = 'http://maps.googleapis.com/maps/api/staticmap?maptype=satellite|' + item.address;
req(mapUrl2)
.pipe(fs.createWriteStream(fs.createWriteStream('/temp/s/' + item.id + '.jpg'))
.on('finish', function () {
resolve("Promised resolved");
}).on('error', function (error) {
reject('Error in creating map', error);
})
});
})
)
}
但是,这并没有按预期工作。我没有收到错误,但它没有生成所有jpg文件。请有人帮助我了解我做错了什么,以及如何更正此错误。只需再次使用Promise.all()
:
function saveMap(addressJson) {
return Promise.all(
//iterate over address json, get each address, call the Google Maps URL and save it.
addressJson.map(function(item) {
return Promise.all([
new Promise(function (resolve, reject) {
var mapUrl = 'http://maps.googleapis.com/maps/api/staticmap?maptype=roadmap|' + item.address;
request(mapUrl)
.pipe(fs.createWriteStream('/temp/r/' + item.id + '.jpg'))
.on('finish', function () {
resolve("Promise resolved");
}).on('error', function (error) {
reject('Error in creating map', error);
})
}),
new Promise(function (resolve, reject) {
var mapUrl2 = 'http://maps.googleapis.com/maps/api/staticmap?maptype=satellite|' + item.address;
req(mapUrl2)
.pipe(fs.createWriteStream(fs.createWriteStream('/temp/s/' + item.id + '.jpg'))
.on('finish', function () {
resolve("Promised resolved");
}).on('error', function (error) {
reject('Error in creating map', error);
})
})
]);
})
)
}
我会:
var长度=10;
var arr1=Array.from({length},(el,i)=>newpromise(re=>re(i));
var arr2=Array.from({length},(el,i)=>newpromise(re=>re(i));
Promise.all([…arr1,…arr2])。然后(console.log.bind(console));
在该代码中有两个return
语句,这就是它不起作用的原因
但是,您真正应该首先从下载中提取您的内容:
function download(url, target) {
return new Promise(function (resolve, reject) {
request(uUrl).pipe(fs.createWriteStream(target))
.on('finish', resolve)
.on('error', reject)
});
}
现在您可以使用它两次。简单地说,我不会尝试只迭代一次数组,而是简单地将其映射两次并对结果进行concat。另一种方法是对每个项目的承诺进行排序
function saveMap(addressJson) {
var mapUrl = 'http://maps.googleapis.com/maps/api/staticmap?maptype=';
return Promise.all(addressJson.map(function(item) {
return download(mapUrl + 'roadmap|' + item.address, '/temp/r/' + item.id + '.jpg');
}).concat(addressJson.map(function(item) {
return download(mapUrl + 'satellite|' + item.address, '/temp/s/' + item.id + '.jpg');
})));
}
一旦您
返回
某个内容,函数就执行完毕。您需要将第一个resolve
调用替换为第二个promise回调的内容。这不会使两个promise(一个用于路线图,另一个用于卫星地图)按顺序运行吗?
function download(url, target) {
return new Promise(function (resolve, reject) {
request(uUrl).pipe(fs.createWriteStream(target))
.on('finish', resolve)
.on('error', reject)
});
}
function saveMap(addressJson) {
var mapUrl = 'http://maps.googleapis.com/maps/api/staticmap?maptype=';
return Promise.all(addressJson.map(function(item) {
return download(mapUrl + 'roadmap|' + item.address, '/temp/r/' + item.id + '.jpg');
}).concat(addressJson.map(function(item) {
return download(mapUrl + 'satellite|' + item.address, '/temp/s/' + item.id + '.jpg');
})));
}