nodejs 同步執行異步函數


有時候要運行某個異步方法, 但不能對它重寫為同步的時候, 就需要此函數進行處理.

實現方式目前有兩個, 一和是使用 c++ 編譯處理, 一種是使用 exec .

如果編譯則需要安裝一系列相關的依賴, 比較麻煩, 對於簡單使用時, 推薦使用 exec.

在開發 mockm(一款感覺簡單而強大的前后端接口聯調工具) 時, 使用到的一個工具庫就引用了一個叫 promise-synchronizer 的庫來進行同步運行異步方法, 感覺用戶安裝起來十分麻煩.

promise-synchronizer 依賴了 deasync 庫, 這個庫需要使用 python 2 編譯. 如果使用者的電腦上沒有 python 2 則安裝出錯, 如果客戶使用 node14+ 則安裝出錯, 因為 node14+ 使用了 python 3.

所以我便對工具進行了重寫, 以下為簡單實現的代碼和示例:

function asyncTosync(fn) { // 同步執行異步函數, 入參和出參需要可序列化, 不會輸出出參數之外的其他信息
  return (...args) => {
    const { writeFileSync, readFileSync } = require(`fs`)
    const fnStr = fn.toString()
    const tempDir = require(`os`).tmpdir().replace(/\\/g, `/`)
    const fileObj = {
      fnFile: `${tempDir}/fnFile_${Date.now()}.js`,
      resFile: `${tempDir}/resFile_${Date.now()}.json`,
      errFile: `${tempDir}/errFile_${Date.now()}.json`,
    }
    writeFileSync(fileObj.fnFile, ``, `utf8`)
    writeFileSync(fileObj.resFile, ``, `utf8`)
    writeFileSync(fileObj.errFile, ``, `utf8`)
    const argsString = args.map(arg => JSON.stringify(arg)).join(', ');
    const codeString = `
      const { writeFileSync } = require('fs')
      const fn = ${fnStr}
      new Promise(() => {
        fn(${argsString})
          .then((output = '') => {
            writeFileSync("${fileObj.resFile}", output, 'utf8')
          })
          .catch((error = '') => {
            writeFileSync("${fileObj.errFile}", error, 'utf8')
          })
        }
      )
    `
    writeFileSync(fileObj.fnFile, codeString, `utf8`)
    console.log(`fileObj`, fileObj)
    require(`child_process`).execSync(`"${process.execPath}" ${fileObj.fnFile}`)
    const res = readFileSync(fileObj.resFile, `utf8`)
    const err = readFileSync(fileObj.errFile, `utf8`)
    return {res, err}
  }
}
const fn = time => new Promise((resolve, reject) => {
  setTimeout(() => resolve(`ok ${time}`), time);
})


const sleep = ms => new Promise(r => setTimeout(r, ms))
console.log(`1s`)
const {res, err} = asyncTosync(sleep)(3e3)
console.log({res, err})
console.log(`5s`)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM