1

Want to initialize a value from a async call, then keep on using that value, I don't know how to await before node loads other code here.

console.log('---- initialize the value during startup ----');
const p1 = (async () => {
    const res = await requestAsync.get('https://nodejs.org/dist/latest-v8.x/docs/api/util.html');
    return res.headers;
})();
const v2 = p1.then(v => (v));

console.log(v2);
console.log('---------- more work after v2 is resolved --------------');

i get

---- initialize the value during startup ----
Promise { <pending> }
---------- more work after v2 is resolved --------------
user3552178
  • 2,719
  • 8
  • 40
  • 67

2 Answers2

3

I'm not sure I understand what you mean, but maybe this is what you want?

async function main() {
  const response = await requestAsync.get('https://n...');
  const headers = response.headers;

  console.log('some other stuff here');
}

main();

Putting everything in a "main" function allows you to wait for you initial request before doing anything else.

Be careful though: this is blocking, so if the request takes a while, nothing will happen in your code until it's done.

bastien girschig
  • 663
  • 6
  • 26
  • the initialization should be quick, so waiting in startup is ok. your solution may not work, since if i have another function wants to use the return value from main(), i may get uninitialized one. – user3552178 Jun 29 '19 at 18:54
  • Well the point of the "main" function is to have everything in there (apart from imports). The main function returns nothing, and nothing should happen outside of it. If you really don't want to do that, you can use the normal promise syntax: ```requestAsync.get('https://nodejs/...').then(response=>console.log(response))``` – bastien girschig Jun 29 '19 at 20:06
  • i c, i wait a little bit see if there're other ways – user3552178 Jun 29 '19 at 20:31
3

Until node.js has top level await (which it currently doesn't), then the usual way of doing things is to just use .then() and put everything that is dependent upon the asynchronous result inside the .then() handler:

requestAsync.get('https://nodejs.org/dist/latest-v8.x/docs/api/util.html').then(result => {
    // put all the rest of your initialization code that 
    // needs this async result here
}).catch(err => {
    // handle errors here
});

If you want to (just for code structure reasons), you can move everything into a function:

requestAsync.get('https://nodejs.org/dist/latest-v8.x/docs/api/util.html')
  .then(startup)
  .catch(handleErr);

function startup(result) {
   // put your startup code here that needs result
}

function handleErr(err) {
   // handle error here
}

Keep in mind that any other startup code will continue because module loading does not block waiting for this async result.


If you have multiple asynchronous operations you want do in a row, then you can chain them:

 requestAsync.get().then(f1).then(f2).catch(err => {....});

Or, you can wrap code in a top level function so you can use await:

 async function startup() {
      let result1 = await f1(...);
      let result2 = await f2(...);
      let result3 = await f3(...);
 }

 startup().then(finalResult => {
    // all async operation done here with finalResult
 }).catch(err => {
    // error starting up
 });
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Node.js now has top-level `await`, but your solution is a lot easier than configuring it with TypeScript currently. – TrueWill Dec 07 '22 at 21:20