簡體   English   中英

Node.js中如何執行同步和異步函數數組

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

我有像 JSON 這樣的配置,我們可以在其中定義任何 JavaScript 函數。 現在我執行了 function ,它將采用該函數數組並執行。 我怎樣才能做到這一點?

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();

如您所見,一個 function 同步和另一個 function 作為asyncawai 將所有 function 定義為async & await似乎很糟糕(創建了很多新的承諾)+我不能將所有 function 也定義為同步。

提前感謝您的回答。

您可以使用Promise.all()來解決一系列承諾。

承諾以外的值將按原樣返回

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, ...). 最著名的是藍鳥。

它實現了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);
});

您應該簡單地將所有函數視為可能返回 promise。 無需區分它們,只需await結果即可。 如果它不是 thenable (read: non-promise) value ,執行將立即繼續 所以只寫

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

如果您希望異步任務同時運行,只需將所有值收集到一個數組中並將它們傳遞給Promise.all 它也可以很好地處理非承諾元素

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

沒有承諾的解決方案。 使用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...

在此示例中,您創建了一個已執行函數的數組,並使用 Promise.all() 和 map 來獲得所有承諾,如果 function 結果。 (在異步 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)) 

也許這是您的解決方案:

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

理想情況下,一切都異步會更干凈。 但如果沒有,這將起作用:

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