Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用bluebird的request.getAsync,如何';管道';归档_Javascript_Node.js_Asynchronous_Promise_Bluebird - Fatal编程技术网

Javascript 使用bluebird的request.getAsync,如何';管道';归档

Javascript 使用bluebird的request.getAsync,如何';管道';归档,javascript,node.js,asynchronous,promise,bluebird,Javascript,Node.js,Asynchronous,Promise,Bluebird,我正在尝试异步获取某个pdf文件的内容。为此,我使用了Promise.mapSeries和request.getAsync和spreadfrombluebird 但是在中,然后我需要使用pipe和createWriteStream直接获得该请求的结果。比如: request(url).pipe(fs.createWriteStream(file)); 这是代码,我正在使用: const Promise = require('bluebird'); const request = Promise

我正在尝试异步获取某个pdf文件的内容。为此,我使用了
Promise.mapSeries
request.getAsync
spread
frombluebird

但是在
中,然后
我需要使用
pipe
createWriteStream
直接获得该
请求的结果。比如:

request(url).pipe(fs.createWriteStream(file));
这是代码,我正在使用:

const Promise = require('bluebird');
const request = Promise.promisifyAll(require('request'), { multiArgs: true });
const fs = Promise.promisifyAll(require("fs"));

const urls = ['http://localhost/test-pdf/one.pdf', 'http://localhost/test-pdf/two.pdf'];

Promise.mapSeries(urls, url => {
    return request.getAsync({url: url, encoding:'binary'}).spread((response, body) => {
        if (response.statusCode == 200){
            let r = {};
            r.name = url.match(/\/([^/]*)$/)[1]; // get the last part of url (file name)
            r.content = body;
            console.log(`Getting ${r.name}`);
            return r;
        }
        else if (response.statusCode == 404){
            console.log(`The archive ${url.match(/\/([^/]*)$/)[1]} does not exists`);
        }
        else throw new Error(`Unsuccessful attempt. Code: ${response.statusCode}`);
    });
}).then((result) => {
    // Here I want to 'pipe' to a file the result from 'getAsync'
}).catch((error) =>{
    console.error(error);
})
我的问题:

如何使用
pipe
函数将
getAsync
的结果通过管道传输到文件?有可能吗


PD:我知道我可以使用
fs.promises
,但我只是想知道是否有可能用我发布的方式来实现它我想答案已经在
中的问题中了。然后()
似乎就是你所寻求的
.pipe()

可能缺少的是
(result)
应该是
(results)
,即由
Promise.mapSeries(URL,…)
产生的所有
{name,content}
对的数组

实际上,您可能不会选择这样编写,因为每个
getAsync()
都需要在任何写入开始之前完成

在大多数情况下(可能是您想要的情况下),最好尽快编写每个成功的
getAsync()
中的内容:

Promise.mapSeries(urls, url => {
    let name = url.match(/\/([^/]*)$/)[1]; // get the last part of url (file name)
    return request.getAsync({'url':url, 'encoding':'binary'}).spread((response, body) => {
        if (response.statusCode == 200) {
            // write `body.content` to file.
        } else if (response.statusCode == 404) {
            throw new Error(`The archive ${name} does not exist`);
        } else {
            throw new Error(`Unsuccessful attempt. Code: ${response.statusCode}`);
        }
    });
}).catch((error) => {
    console.error(error);
});
更进一步,您可能会选择更好地处理错误,例如,您可能希望:

  • 捕获单个url/获取/写入错误
  • 编译成功/失败统计数据
可能是这样的:

Promise.mapSeries(urls, url => {
    let name = url.match(/\/([^/]*)$/)[1] || ''; // get the last part of url (file name)
    if(!name) {
        throw new RangeError(`Error in input data for ${url}`);
    }
    return request.getAsync({'url':url, 'encoding':'binary'}).spread((response, body) => {
        if (response.statusCode == 200) {
            // write `body.content` to file.
            return { name, 'content': body };
        } else if (response.statusCode == 404) {
            throw new Error(`The archive ${name} does not exist`);
        } else {
            throw new Error(`Unsuccessful attempt. Code: ${response.statusCode}`);
        }
    })
    .catch(error => ({ name, error }));
}).then((results) => {
    let successes = results.filter(res => !res.error).length;
    let failures = results.filter(res => !!res.error).length;
    let total = results.length;
    console.log({ successes, failures, total }); // log success/failure stats
}).catch((error) => {
    console.error(error); // just in case some otherwise uncaught error slips through
});

谢谢你的回答,有趣的一个!我投了赞成票,我要试试你的想法。我稍后会回来。只要指出第一个
.catch
,应该是
.catch(error=>({name,error}))有两种方法可以从箭头函数返回对象:要么向块体添加返回
x=>{return{}
要么将其标记为表达式
x=>({})
-这两种方法都有效且有效。好的,我已经尝试了你的代码,我喜欢它,但是。。。。我的问题是:在哪里可以将函数
pipe
放入
request.getAsync(url).spread((响应,主体)=>{})
???有可能吗???您希望使用哪个
管道
功能?你在哪里读到的?你对它有什么期待,但还没有实现?好吧,现在我明白了。谢谢你的帮助和时间,我的朋友。作为评论——在下面的回答和评论之后——我只想引用下面的话:“流式响应(例如
.pipe(…)
)不鼓励使用,因为请求承诺会使大型请求的内存占用增加到不必要的高。请使用原始请求库。您可以在同一项目中使用这两个库“
Promise.mapSeries(urls, url => {
    let name = url.match(/\/([^/]*)$/)[1] || ''; // get the last part of url (file name)
    if(!name) {
        throw new RangeError(`Error in input data for ${url}`);
    }
    return request.getAsync({'url':url, 'encoding':'binary'}).spread((response, body) => {
        if (response.statusCode == 200) {
            // write `body.content` to file.
            return { name, 'content': body };
        } else if (response.statusCode == 404) {
            throw new Error(`The archive ${name} does not exist`);
        } else {
            throw new Error(`Unsuccessful attempt. Code: ${response.statusCode}`);
        }
    })
    .catch(error => ({ name, error }));
}).then((results) => {
    let successes = results.filter(res => !res.error).length;
    let failures = results.filter(res => !!res.error).length;
    let total = results.length;
    console.log({ successes, failures, total }); // log success/failure stats
}).catch((error) => {
    console.error(error); // just in case some otherwise uncaught error slips through
});