简体   繁体   English

Node.js中如何执行同步和异步函数数组

[英]How to execute a array of synchronous and asynchronous functions in Node.js

I have config like JSON where we can define any JavaScript functions inside.我有像 JSON 这样的配置,我们可以在其中定义任何 JavaScript 函数。 Now I have execution function which would take that array of functions and execute.现在我执行了 function ,它将采用该函数数组并执行。 How can I do that?我怎样才能做到这一点?

const listOfFuncs = [
  {
    "func1": (...args) => console.log(...args)
  },
  {
    "func2": async (...args) => {
      return await fetch('some_url');
    }
  }
]

function execute() {
  // how to execute the above array of functions now ?
}

// Should this be called as await execute()? 
execute();

As you can see one function sync & another function as async & awai t.如您所见,一个 function 同步和另一个 function 作为asyncawai Defining everything function as async & await seems bad ( creating a lot of new promises ) + I can't define all function as synchronous also.将所有 function 定义为async & await似乎很糟糕(创建了很多新的承诺)+我不能将所有 function 也定义为同步。

Thanks for your answer in advance.提前感谢您的回答。

You can use Promise.all() to resolve an array of promises.您可以使用Promise.all()来解决一系列承诺。

Values other than promises will be returned as-is承诺以外的值将按原样返回

const listOfFuncs = [
    () => 45,
    async () => new Promise(resolve => {
        setTimeout(() => resolve(54), 100);
    })
];

async function execute() {
  return Promise.all(listOfFuncs.map(func => func()));
}

// execute() will return a Promise which resolves to an array
// containing all results in the same order as the functions.
execute().then(result => console.log(result));

// Logs: [45, 54] after 100ms

There is no native function to resolve an object containing promises, however some libraries implement alternative Promise API, to make it easier to use more complex pattern (cancellation, races, ...). There is no native function to resolve an object containing promises, however some libraries implement alternative Promise API, to make it easier to use more complex pattern (cancellation, races, ...). The most well known is Bluebird.最著名的是蓝鸟。

It implements a Promise.props methods which almost do what you want: http://bluebirdjs.com/docs/api/promise.props.html它实现了Promise.props方法,几乎可以满足您的要求: http://bluebirdjs.com/docs/api/promise.props.html

var Promise = require("bluebird");

Promise.props({
    pictures: getPictures(),
    comments: getComments(),
    tweets: getTweets()
}).then(function(result) {
    console.log(result.tweets, result.pictures, result.comments);
});

You should simply treat all your functions as potentially returning a promise.您应该简单地将所有函数视为可能返回 promise。 No need to distinguish them, just await the result.无需区分它们,只需await结果即可。 The execution will carry on immediately if it was not a thenable (read: non-promise) value .如果它不是 thenable (read: non-promise) value ,执行将立即继续 So just write所以只写

async function execute() {
  for (const func of listOfFuncs) {
    await func();
  }
}

If you want the asynchronous tasks to run concurrently, just collect all values into an array and pass them to Promise.all .如果您希望异步任务同时运行,只需将所有值收集到一个数组中并将它们传递给Promise.all It deals with non-promise elements just fine as well.它也可以很好地处理非承诺元素

async function execute() {
  await Promise.all(listOfFuncs.map(func => func()));
}

Solution without promises.没有承诺的解决方案。 Use process.nextTick(callback) or setImmediate使用process.nextTick(callback)setImmediate

const listOfFuncs = [
    {
        "func3": setImmediate(execute, "setImmadiate executes after process.nextTick")
    }, 
    {
        "func2": process.nextTick(execute, "process.nextTick executes after sync function but before setImmediate")
    },
    {
        "func1": execute
    }
]

function execute() {
    console.log("executing...", arguments[0]);

}

execute(listOfFuncs);

// results: 
// executing...[...]
// executing...process.tick
// executing...setImmediate...

In this example, you create an array of the executed functions and use the Promise.all() with a map to get all promisses if the function results.在此示例中,您创建了一个已执行函数的数组,并使用 Promise.all() 和 map 来获得所有承诺,如果 function 结果。 (in a case of an async function the function returns a promise-value, which you can await) (在异步 function 的情况下,function 返回一个承诺值,您可以等待)

function isPromise(promise) {  
    return !!promise && typeof promise.then === 'function'
}
let functions = [
  (() => {})(),
  (async () => {})()
];
await Promise.all(functions.map(function_result => (isPromise(function_result) ? function_result : undefined)) 

Maybe this is a solution for you:也许这是您的解决方案:

await Promise.all([
  (async () => {
    //Your Function here
  })(),
]);

Ideally having everything async would be cleaner.理想情况下,一切都异步会更干净。 But if not, this would work:但如果没有,这将起作用:

async function execute(...args) {
  for (let i = 0; i < listOfFuncs.length; i++) {
    if (listOfFuncs[i].constructor.name === "AsyncFunction") {
      await listOfFuncs[i](...args);
    } else {
      listOfFuncs[i](...args);
    }
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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