2017-08-19 26 views
0

我想找到一些方法來寫我的一般promisify函數來使用異步和socket.io等待
這是我的代碼第一個未能完成,而第二個成功沒有問題。使用這兩種方式來提示Socket.IO的server.close有什麼區別?

這兩者有什麼區別?爲什麼第一個失敗?

function promisify (func) { 
    return new Promise((resolve, reject) => func(() => { 
     resolve()  
     console.log('closeServer') 
    }))} 
async function timer1() { 
    await Promise.resolve(promisify(server.close)) 
} 



function closeServer() { 
    return new Promise((resolve, reject) => server.close(() => { 
     resolve() 
     console.log('closeServer') 
    }))} 
async function timer2() { 
    await Promise.resolve(closeServer()) 
} 

讓我告訴你們的日誌,
第二個

> nodemon src/index.js --exec babel-node --presets es2015 

[nodemon] 1.11.0 
[nodemon] to restart at any time, enter `rs` 
[nodemon] watching: *.* 
[nodemon] starting `babel-node src/index.js --presets es2015` 
Server listening at port 3000 
^C(node:28061) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): TypeError: Cannot read property '_handle' of undefined 
(node:28061) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. 

第二

> nodemon src/index.js --exec babel-node --presets es2015 

[nodemon] 1.11.0 
[nodemon] to restart at any time, enter `rs` 
[nodemon] watching: *.* 
[nodemon] starting `babel-node src/index.js --presets es2015` 
Server listening at port 3000 
^CcloseServer 
+0

'爲什麼第一次失敗會以什麼方式失敗?順便說一下,這些函數都不會拒絕 –

+0

「*'resolve(); if(false)reject(err)'*」 - Wat? – Bergi

+0

我認爲這是[如何在回調中訪問正確'this'/context的副本](https://stackoverflow.com/q/20279484/1048572) - 這是您的代碼之間的明顯區別:'close '使用'promisify'時不會被稱爲'server'的方法。 – Bergi

回答

0

你的第一個立即調用的函數,當它被稱爲回來,以undefined解決。它沒有做任何事情傳遞數據,或處理錯誤;實際上,如果if (false)並非總是假,那麼當嘗試獲取err標識符的值時,該代碼將失敗,返回ReferenceError

如果您想編寫一個函數將一個Node類型的回調API轉換爲啓用promise的函數,那就相當簡單了。你呈現回調的最後一件事的功能在它的參數列表預期,而且它調用回調與通常err, data參數:

const promisify = func => (...args) => new Promise((resolve, reject) => { 
    func(...args, (err, data) => { 
     if (err) { 
      reject(err instanceof Error ? err : new Error(err)); 
     } else { 
      resolve(data); 
     } 
    }); 
}); 

它返回,調用它時,會調用原始文件傳遞函數沿着它的所有論點加上最後的回調,並返回一個承諾。當回調被調用時,它假定它的格式爲err, data,如果err是真的,則拒絕承諾,否則解決。它確保拒絕是一個Error(我的首選是總是使用Errorthrowreject;您的風格可能會有所不同)。

用法:

const readFileP = promisify(fs.readFile); 

然後,你要使用的結果是:如果你搜索,有你做它功能豐富的圖書館在那裏

readFileP("filename", "utf-8") 
    .then(data => { /* ... */ }) 
    .catch(err => { /* ... */ }); 

然而具有更多的靈活性,並且也經過測試。

相關問題