Nodejs 8 有一個新的工具函數 util.promisify()。他將一個接收回調函數參數的函數轉換成一個返回Promise的函數。html
若是你給如下命令傳入文件路徑,則會輸出文件內容node
// echo.js const {promisify} = require('util'); const fs = require('fs'); const readFileAsync = promisify(fs.readFile); // (A) const filePath = process.argv[2]; readFileAsync(filePath, {encoding: 'utf8'}) .then((text) => { console.log('CONTENT:', text); }) .catch((err) => { console.log('ERROR:', err); });
注意:在第一行,程序使用promisify()
轉換基於回調函數的方法fs.readFile()
成一個返回promise
的一個函數git
下面的代碼片斷顯示這個腳本如何使用的github
$ node echo.js echo.js CONTENT: const {promisify} = require('util'); ··· $ node echo.js unknown.txt ERROR: { Error: ENOENT: no such file or directory, ··· }
async
函數一樣的功能,可是經過async函數實現npm
// echoa.js const {promisify} = require('util'); const fs = require('fs'); const readFileAsync = promisify(fs.readFile); const filePath = process.argv[2]; async function main() { try { const text = await readFileAsync(filePath, {encoding: 'utf8'}); console.log('CONTENT:', text); } catch (err) { console.log('ERROR:', err); } } main();
下面的函數的回調函數接收多於一個的參數(除了error參數)數組
child_process.execpromise
child_process.execFileasync
dns.lookup函數
dns.lookupService工具
fs.read
fs.write
若是你轉換這些函數爲promise,它會返回一個對象(由多個參數組成的對象,而不是一個值)。例如,dns.lookup
的回調函數包含下面幾個參數
err : Error
address : string
family : integer
轉換成Promise以後,它的參數將會變成{address, family}
這樣一個對象
const util = require('util'); const dns = require('dns'); const lookupAsync = util.promisify(dns.lookup); lookupAsync('nodejs.org') .then(obj => console.log(obj)); // { address: '104.20.23.46', family: 4 }
promisify()
經過內部符號internal/util/customPromisifyArgs
處理非標準回調函數。所以不推薦傳入一個非標準的回調函數,也不該該去轉換咱們本身實現的回調(ps:本身就直接寫Promise就行了。。。)
promisified
的API來源於util.promisify.custom
,它容許您將一個promisified
版本附加到一個基於回調的函數。 在如下示例中,fooAsync
是foo
的promisified
版本
const util = require('util'); function foo() { return 'abc'; } async function fooAsync() { return 'abc'; } foo[util.promisify.custom] = fooAsync; console.log(util.promisify(foo) === fooAsync); // true
promisified
版本的標準函數如今,有兩個標準函數有定製的promisified
版本
> setImmediate[util.promisify.custom] [Function] > setTimeout[util.promisify.custom] [Function]
Jordan Harband寫了一個庫a polyfill for util.promisify(),用來兼容promisify,使用方法以下
須要注意:
js必須支持es5以上語法
必須支持Promise
待完善中
安裝
npm install util.promisify
使用方式有兩種
第一種,檢查是否有內置實現(Node 8)或者使用 polyfill (舊的Node版本)
const promisify = require('util.promisify'); const fs = require('fs'); const readFileAsync = promisify(fs.readFile);
第二種,在舊版本的Node上使用補丁模塊
const util = require('util'); require('util.promisify').shim(); const fs = require('fs'); const readFileAsync = util.promisify(fs.readFile);