为什么NodeJS不使用Promise作为readFile API?
在书https://pragprog.com/book/tbajs/async-javascript中 ,我发现这个:
Node的早期迭代在其非阻塞API中使用了Promises。 然而,2010年2月,Ryan Dahl做出了转向现在熟悉的callback(err,results …)格式的决定,理由是Promise是属于“用户区”的更高级别的构造。
这看起来很让人困惑,因为作为一个读取文件的API,这个
fs.readFile('/etc/passwd') .onSuccess(function(data){console.log(data)}) .onError(function(err){throw err})
看起来比这更好:
fs.readFile('/etc/passwd', function (err, data) { if (err) throw err; console.log(data); });
有没有人有关于为什么“承诺是一个更高级别的构造”会停止在NodeJS API中使用的想法?
未来是承诺:
NodeJS 将使用新的API的承诺。 实际上目前正在讨论如何 。 之前在0.2节点使用Promise的尝试由于摩擦和性能问题而失败。
什么必须先发生:
现在,承诺是一种本地语言function,但是在将其发布到核心API之前,必须进行以下操作:
-
承诺必须是已经发生的本地语言结构。 - 最近宣布的NodeJS和io.js合并必须发生 – 时间可能短短几个月。
- v8(JavaScript引擎)团队必须完成私有符号的工作,这将实现快速承诺创build。 目前,承诺构造函数是在本地承诺中创build承诺的唯一方式,它分配了一个相对昂贵的闭包。 目前,Domenic正在与io.js和v8团队密切合作,确保正确完成这项工作。
- V8团队必须优化承诺实施,目前原生承诺会一直失去像蓝鸟这样的用户级实施。 这现在也正在发生。
一旦所有这些都发生,API将被分离,并且包含promise的版本将被整合到核心中。 这是一个漫长而无趣的讨论 – 在io.js / NG回购中有一个更好的讨论 ,但都没有太多的信息。
今天可以做什么
像蓝鸟这样的库为您提供了一种工具,可以快速高效地将callbackAPI转换为承诺 。 您今天可以使用它们并获得该function。
历史上callback是默认的性能原因,但…
2017年更新/节点8:核心现在支持承诺!
Node.js从Node v8.x开始支持promise。 这些API仍然以callback风格编写(为了向后兼容等),但是现在在节点核心中有一个实用程序类来将基于callback的API转换为基于承诺的API(类似于蓝鸟):
https://nodejs.org/api/util.html#util_util_promisify_original
从Node.js文档:
例如:
const util = require('util'); const fs = require('fs'); const stat = util.promisify(fs.stat); stat('.').then((stats) => { // Do something with `stats` }).catch((error) => { // Handle the error. });
或者,等价地使用asynchronous函数:
const util = require('util'); const fs = require('fs'); const stat = util.promisify(fs.stat); async function callStat() { const stats = await stat('.'); console.log(`This directory is owned by ${stats.uid}`); }
Promise是一个库,在使用promise时需要从函数返回Promise构造函数,但是使用callback函数链可以实现同样的事情,这就是为什么“Promise是一个更高级的构造”
参考: 节点js中的承诺