为什么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中的承诺