can't do http request with async and await

2019-08-09 10:24发布

Trying to use async and await to do http request in nodejs, but got error. Any ideas? Thx

got response: 
undefined
/home/tom/learn/node/node_modules/node-rest-client/lib/node-rest-client.js:539
            callback(parsedData,res);
            ^

TypeError: callback is not a function
    at /home/tom/learn/node/node_modules/node-rest-client/lib/node-rest-client.js:539:13
    at Object.parse (/home/tom/learn/node/node_modules/node-rest-client/lib/nrc-parser-manager.js:151:3)
    at ConnectManager.handleResponse (/home/tom/learn/node/node_modules/node-rest-client/lib/node-rest-client.js:538:32)
    at ConnectManager.handleEnd (/home/tom/learn/node/node_modules/node-rest-client/lib/node-rest-client.js:531:18)
    at IncomingMessage.<anonymous> (/home/tom/learn/node/node_modules/node-rest-client/lib/node-rest-client.js:678:34)
    at emitNone (events.js:110:20)
    at IncomingMessage.emit (events.js:207:7)
    at endReadableNT (_stream_readable.js:1059:12)
    at _combinedTickCallback (internal/process/next_tick.js:138:11)
    at process._tickCallback (internal/process/next_tick.js:180:9)

Here is the source code for the script

var Client = require('node-rest-client').Client;
var client = new Client();
async function test1() {
    response = await client.get("http://localhost/tmp.txt");
    console.log("got response: ");
    console.log(response.headers);
};
test1();

nodejs is of version v8.4.0, on ubuntu 14.04.

2条回答
2楼-- · 2019-08-09 11:14

async/await don't just magically work with functions that expect callbacks. If client.get() is expecting a callback as an argument, you HAVE to pass a callback if you're going to use it. async/await work with asynchronous operations that return promises and they operate on those promises. They do not magically let you skip passing callbacks to functions designed for a callback. I'd suggest a lot more reading about how to actually use async and await.

In general, the path to async/await is to first design all your async operations to use promises and .then() handlers. Then, after that is all working, you can declare a function as async that you want to use await in and then inside those async-declared functions you can call functions that return promises with await instead of using .then() handlers with them. There are no magic shortcuts here. Start with a promise design.

Here's a simple promise example:

// asynchronous function that returns a promise that resolves to
// the eventual async value
function delay(t, val) {
   return new Promise(resolve => {
       setTimeout(() => {
           resolve(val);
       }, t);
   });
}


function run() {
    return delay(100, "hello").then(data => {
        console.log(data);
        return delay(200, "goodbye").then(data => {
           console.log(data);
        });
    }).then(() => {
        console.log("all done");
    });
}

run();

And, here's the same adapted to use async/await:

// function returning a promise declared to be async
function delay(t, val) {
   return new Promise(resolve => {
       setTimeout(() => {
           resolve(val);
       }, t);
   });
}

async function run() {
    console.log(await delay(100, "hello"));
    console.log(await delay(200, "goodbye"));
    console.log("all done");
}

run();

Both of these examples produce the same output and same output timing so hopefully you can see the mapping from promises to async/await.

查看更多
该账号已被封号
3楼-- · 2019-08-09 11:14

await requires its argument to return a promise. And the reason you are getting this error is that client.get("http://localhost/tmp.txt"); doesn't return a promise.

So, There are 2 ways you can resolve this issue.

  1. Explicitly return a promise
  2. Use other libraries that return promises. Example : https://www.npmjs.com/package/node-rest-client-promise
查看更多
登录 后发表回答