Home > Blockchain >  How should i run a async function in sync function in NodeJS?
How should i run a async function in sync function in NodeJS?

Time:08-19

I have a vue project that use CDN to getting it libs for running. Now I want to add a integrity property on the script label to verify the script it pull from CDN. And I want the code automatic generate the hash of script and insert is to the dist when i build the project.

I want a some sync function like this:

function integrityWapper ({ css, js }) {
  const hash = require('crypto-js').SHA384
  const icss = []; const ijs = []
  for (const i in css) {
    icss.push([css[i], hash(GettingScriptContentFromWeb(css[i]))])
  }
  for (const i in js) {
    ijs.push([js[i], hash(GettingScriptContentFromWeb(js[i]))])
  }
  return { icss, ijs }
}

Obviously, this function cannot be async cause i am trying to generate config for vue.config.js, so the GettingScriptContentFromWeb function must also be sync.
Is there a way turn call async function(i mean axios.get) in sync function and wait it to finish?

CodePudding user response:

Is there a way turn call async function(i mean axios.get) in sync function and wait it to finish?

No, there is not. axios.get() is asynchronous and you cannot get its result synchronously.

You will have to rewrite your code to use an asynchronous design. Probably, GettingScriptContentFromWeb() needs to return a promise and integrityWrapper() needs to use that promise and also needs to return a promise. The caller of integrityWrapper() then needs to use .then() or await on the promise that integrityWrapper() will return to get the resolved value.

For example, if you changed GettingScriptContentFromWeb() to return a promise that resolves to it's value, then you could do this:

async function integrityWapper ({ css, js }) {
  const hash = require('crypto-js').SHA384
  const icss = []; const ijs = []
  for (const i in css) {
    icss.push([css[i], hash(await GettingScriptContentFromWeb(css[i]))])
  }
  for (const i in js) {
    ijs.push([js[i], hash(await GettingScriptContentFromWeb(js[i]))])
  }
  return { icss, ijs }
}

integrityWrapper(...).then(result => {
    // use the asynchronously retrieved result here
}).catch(err => {
    // got some error here
});

P.S. if css or js are arrays, then you should be using for/of to iterate arrays, not for/in. If they are objects, then you can use for/in to iterate their enumerable properties.

CodePudding user response:

As you are dealing with http api's the result is always going to be asynchronous. From the context, i am assuming you want to execute this script when you are building the project, something like yarn dostuff.

This can be achieved like by wrapping the async function in a self executing function

index.js

async function integrityWapper ({ css, js }) {
  const hash = require('crypto-js').SHA384
  const icss = []; const ijs = []
  for (const i in css) {
    icss.push([css[i], hash(await GettingScriptContentFromWeb(css[i]))])
  }
  for (const i in js) {
    ijs.push([js[i], hash(await GettingScriptContentFromWeb(js[i]))])
  }
  return { icss, ijs }
}

const executor = (async ()=>{
  await integrityWapper({
    css: process.env.CSS,
    js: process.env.JS
  });
})();

export default executor;

And then add a script in package.json

  "scripts": {
    "dostuff": "node index.js",
    "custom-build": "yarn dostuff && yarn build"
  },

Something on the lines of above

Hope i made sense

  • Related