0

I've written a little code snipped for a http request. After I realized request is async, I rewrote my code with a promise. But it's telling me that the promise is pending. I have absolute no idea why it is wrong. Here my code:

function verifyUser(uname,pword){
    var options = {
        url: 'CENSORED',
        method: 'POST',
        headers: headers,
        form: {'Username':uname, 'Password':pword, 'Key':key},
        json:true
    }
    return new Promise((r,j) => request(options,(error,response,body)=>{
        if(error){
            console.log("[ERROR] Promise returned error");
            throw j(error);
        }
        r(body);
    }))
} 
async function receiveWBBData(uspass,passwd){
    const data = await verifyUser(uspass,passwd);
    return data;
}

var test1 = receiveWBBData("r0b","CENSORED");
console.log(test1);`

Thanks in advance!

RobDeFlop
  • 59
  • 1
  • 11
  • 1
    You don'y need to `throw j(error);`, just call `j` with the error. Also, use an `else` for `r(body)` since otherwise you can potentially try to `reject` _and_ `resolve`. Not a huge issue, but confusing nonetheless. In all likelihood your promise remains `pending` because it never reaches the `resolve` function, so that means your `request` isn't working. Can you post code for that as well? *Update* @YuryTarabanko caught the culprit. – somethinghere Jul 02 '18 at 13:41
  • 3
    By the time you log it it is still pending. You need to do `receiveWBBData("r0b","CENSORED").then(console.log)` – Yury Tarabanko Jul 02 '18 at 13:42
  • `request(options,(error,response,body)` i thought this is the function inside a promise – RobDeFlop Jul 02 '18 at 13:43
  • Yury's Solution is working but can i return the data in .then() ? Its important that I can work with the received data – RobDeFlop Jul 02 '18 at 13:44
  • "can i return the data in .then()" you can. But you'd still need to use `then` to get the data. I mean `receiveWBBData("r0b","CENSORED").then(transform).then(consume)` not `data = receiveWBBData("r0b","CENSORED"); // data is a promise not a value` – Yury Tarabanko Jul 02 '18 at 13:47
  • can you maybe give me an example? I have absolutely no idea about async nodejs and want to learn it. – RobDeFlop Jul 02 '18 at 13:48
  • A promise is an object, not data - your promise can pass the data to the handler you passed to the promise using `then`. So `myPromise.then(function( dataAvailableInFunction ){ ...do with dataAvailableInFunction... })`. – somethinghere Jul 02 '18 at 13:54
  • I have absolutely no clue about this. `var test1= receiveWBBData("r0b","CENSORED").then(function(data){ var outputdata = data; return outputdata; }); console.log(test1); ` but it is still pending – RobDeFlop Jul 02 '18 at 13:57
  • 1
    Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Estus Flask Jul 02 '18 at 14:14
  • @RobDeFlop You are trying to return from async call. Plz read the linked question. TL;DR; it is impossible. – Yury Tarabanko Jul 02 '18 at 14:21

2 Answers2

1

receiveWBBData is async. Therefore, test1 is a promise. If you want to log the result, do test1.then(console.log).catch(console.error), or use var test1 = await receiveWBBData(/*...*/) if you want the result in your variable. Note that await can only be used in async functions.

Also, as @somethinghere mentionned, you should not throw your promise rejection, you should return it.

  • I don't want to log the result. I need the result to work with it in other functions. Therefore, i have to return the data received from the request. And I have still no idea how to solve my issue. – RobDeFlop Jul 02 '18 at 14:02
  • @RobDeFlop You need to get a promise and chain it with `then` (or `await`, which is syntactic sugar for `then) in a place you process data. There's no way to return the actual data when there's already a promise. This is the problem [this infamous question](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) addresses. – Estus Flask Jul 02 '18 at 14:17
  • So, var test1 = await receiveWBBData("r0b","Censored") shall work? – RobDeFlop Jul 02 '18 at 14:19
  • @RobDeFlop Yes. Of course, this means that this should happen inside `async` function. – Estus Flask Jul 02 '18 at 14:21
0

An async function always returns a promise. In order to "unwrap" a promise, you need to await on it, so you need var test1 = await receiveWBBData("r0b","CENSORED");.

Top-level await is not part of the language yet, so I'd recommend you add a function called main() or run() and just call that when your script starts.

async function receiveWBBData(uspass,passwd){
  const data = await verifyUser(uspass,passwd);
  return data;
}

async function main() {
  var test1 = receiveWBBData("r0b","CENSORED");
  console.log(test1);`
}

main().catch(error => console.error(error.stack));
vkarpov15
  • 3,614
  • 24
  • 21