摘要:只此只要事先判斷是否爲async函數,就能使用恰當的調用方法。在Node.JS中,如果你即不喜歡回調代碼嵌套,也不喜歡promise的鏈式寫法,可以使用async/await將程序改造成順序執行的。

在Node.JS中,如果你即不喜歡回調代碼嵌套,也不喜歡promise的鏈式寫法,可以使用async/await將程序改造成順序執行的。參見: node.js將回調函數嵌套改造成順序執行

async/await本質上也是由Promise實現的,具體原理可在網上搜索,那麼調用時和普通函數調用有何不同?

下面是一個將函數回調封裝成的promise函數:

const util = require('util')

const callbackFunc = function(cb) {
  setTimeout(function() {
    console.log('async done')
    cb && cb(null, 1)
  }, 1000)
}

const asyncFunc = util.promisify(callbackFunc)

const asyncCall = async function() {
  let result = await asyncFunc()
  console.log(result)
}

如果直接調用:

asyncCall();
console.log(2);

輸出結果可能跟你想的不太一樣,輸出結果先輸出了 2:

2
async done
1

有很多方法可以解決這個問題.

使用async函數調用

因爲 await 只能在async中調用,因此可以

(async () => {

  await asyncCall()
  console.log(2)

})();

輸出結果正常

async done
1
2

使用promise調用

async函數本質上返回了一個promise函數,在沒有async修飾的普通函數中可以:

asyncCall()
 .then(() => {
   console.log(2)
 })

還可以使用async和回調相結合:

const asyncCall = async function(cb) {
 let result = await asyncFunc()
 console.log(result)
 cb && cb()
}

asyncCall(function() {
 console.log(2)
})

只此只要事先判斷是否爲async函數,就能使用恰當的調用方法。那麼如何判斷這個函數是否爲async的呢?

判斷是否爲async函數

使用util

可使用 util 內置的判斷判斷方法來判斷:

const util = require('util')
util.types.isAsyncFunction(function foo() {}); // Returns false
util.types.isAsyncFunction(async function foo() {}); // Returns true

使用構造函數

也可使用 constructor.name 來判斷

const isAsync = myFunction.constructor.name === "AsyncFunction";

在mocha中使用async

使用mocha自動化測試時,已經完全支持async函數,不過使用上略有不同。

傳統函數需要偉入回調並執行:

it('test callbak', function(done) {
  ...
  done()
})

async不需要傳遞迴調函數,會自動處理error

it('test async', async function() {
  ...
})
相關文章