简体   繁体   中英

Add the result of a chained promise into promise.all()

I try construct a promise, named downloadTextPromise , to download a file and then in Promise.all() to read the file content. However, I still cannot read the file content in Promise.all().then .

I suspect that downloadTextPromise is a two-step promise, so only the first step (HTTP GET) is pushed into promises array. But I have little idea how to fix it.

Any hint? any solution that works is welcoming, request-promise-native package is not compulsory.

My code is as below:

const request = require("request-promise-native");
let promises = [];

//put several promises into promises array;
.....

let downloadTextPromise = request.get("http://example.com/xyz.txt").pipe(fs.createWriteStream(`~/xyz.txt`));

promises.push(downloadTextPromise);
Promise.all(promises).then(() => {
    //I need xyz.txt content at this stage, but it is not ready immediately.
}

Firstly, check if downloadTextPromise is actually a promise. The library's documentation doesn't mention how pipe works. If it returns a native promise, you can do console.log(downloadTextPromise instanceof Promise) . Otherwise, you can try console.log(!!downloadTextPromise.then) .

If it's a promise, then one possibility is that the promise is resolved synchronously after the the stream ends. The code to actually write the file is added to the message queue. In this case, you can fix it by doing:

Promise.all(promises).then(() => {
    setTimeout(() => {
        // Do stuff with xyz.txt
    }, 0);
}

The issue is the writeStream part, so I should build a function returning correct promise.

I don't find the way to construct one returning a promise from request.get().pipe() , instead I use request.get().then() and fs.writeFile() as below.

However, Another problem appears from the new solution: This fs.writeFile works all OK for txt files; for mp3 or mp4, the function returns no error, but the file content is invalid for further processing in Promise.all().then() .

function downloadTextPromise() {
    return new Promise((resolve, reject) => {
        rp.get("http://example.com/xyz.txt").then(data => {
          fs.writeFile("./xyz.txt, data, err => {
            if (err) reject(err);
            resolve(true);
          });
        });
    });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM