为什么 NodeJS 不对 readFile API 使用 Promise?
Why does NodeJS NOT use Promise for the readFile API?
在书 https://pragprog.com/book/tbajs/async-javascript 中,我找到了这个:
Node’s early iterations used Promises in its nonblocking API. However,
in February 2010, Ryan Dahl made the decision to switch to the
now-familiar callback(err, results...) format, on the grounds that
Promises are a higher-level construct that belongs in “userland.”
我看起来很困惑,因为作为 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);
});
有人知道为什么 "Promises are a higher-level construct" 会阻止自己在 NodeJS API 中使用吗?
Promises 是一个库,当使用 promise 时它需要 return 从函数中创建 Promise 构造函数,但使用回调函数链接同样的事情是可以实现的,这就是为什么 "Promises are a higher-level construct"
Node v8 附带 util.promisify
,可将回调 API 转换为 promises,Node v10 附带原生 promises 支持(实验性):
const fs = require('fs').promises;
// in an async function:
let data = await fs.readFile('/etc/passwd');
console.log(data);
未来是承诺:
NodeJS 将 对新的 API 使用 promises。事实上,目前正在讨论如何。由于摩擦和性能问题,多年前在 0.2 中尝试在节点中使用 Promises 失败了。
首先要发生的事情:
现在 promises 是一种本地语言特性,但在它们成为核心之前必须发生以下情况 APIs:
Promise 必须是本地语言结构这已经发生了。
最近宣布的 NodeJS 和 io.js 合并必须发生 - 时间框架可能只有短短几个月。
v8(JavaScript 引擎)团队必须完成私有符号的工作,这将使快速承诺创建成为可能。目前,promise 构造函数是在原生 promises 中创建 promises 的唯一方法,它分配一个相对昂贵的闭包。目前,Domenic 正在与 io.js 和 v8 团队密切合作,以确保正确完成这项工作。
v8 团队必须优化 promise 实现,目前本机 promise 一直输给 bluebird 等用户态实现。现在也是这样。
一旦所有这些发生,API 将被分叉,一个包含 promises 的版本将被集成到核心中。 Here is a long and uninteresting discussion 关于它 - 在 io.js/NG 存储库中有一个更好的,但两者都没有提供太多信息。
今天可以做什么
像 bluebird give you tools to instantly convert a callback API to promises 这样的库以一种快速有效的方式。您现在就可以使用它们并获得该功能。
历史上,出于性能原因,回调是默认设置,但是...
2017 年更新/节点 8:核心现在支持 Promise!
Node.js 自 Node v8.x 起支持 promises。这些 API 仍然以回调方式编写(为了向后兼容等),但是现在节点核心中有一个实用程序 class 可以将基于回调的 API 转换为基于承诺的 API(类似于 bluebird):
https://nodejs.org/api/util.html#util_util_promisify_original
来自 Node.js 文档:
For example:
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.
});
Or, equivalently using async functions:
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}`);
}
2018 年更新/节点 10:新 fs.promises API
fs.promises API 提供了一组替代的异步文件系统方法,return Promise 对象而不是使用回调。 API 可通过 require('fs').promises.
访问
https://nodejs.org/api/fs.html#fs_fs_promises_api
(目前处于实验阶段,但在最新节点上运行完美)
在书 https://pragprog.com/book/tbajs/async-javascript 中,我找到了这个:
Node’s early iterations used Promises in its nonblocking API. However, in February 2010, Ryan Dahl made the decision to switch to the now-familiar callback(err, results...) format, on the grounds that Promises are a higher-level construct that belongs in “userland.”
我看起来很困惑,因为作为 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);
});
有人知道为什么 "Promises are a higher-level construct" 会阻止自己在 NodeJS API 中使用吗?
Promises 是一个库,当使用 promise 时它需要 return 从函数中创建 Promise 构造函数,但使用回调函数链接同样的事情是可以实现的,这就是为什么 "Promises are a higher-level construct"
Node v8 附带 util.promisify
,可将回调 API 转换为 promises,Node v10 附带原生 promises 支持(实验性):
const fs = require('fs').promises;
// in an async function:
let data = await fs.readFile('/etc/passwd');
console.log(data);
未来是承诺:
NodeJS 将 对新的 API 使用 promises。事实上,目前正在讨论如何。由于摩擦和性能问题,多年前在 0.2 中尝试在节点中使用 Promises 失败了。
首先要发生的事情:
现在 promises 是一种本地语言特性,但在它们成为核心之前必须发生以下情况 APIs:
Promise 必须是本地语言结构这已经发生了。最近宣布的 NodeJS 和 io.js 合并必须发生 - 时间框架可能只有短短几个月。v8(JavaScript 引擎)团队必须完成私有符号的工作,这将使快速承诺创建成为可能。目前,promise 构造函数是在原生 promises 中创建 promises 的唯一方法,它分配一个相对昂贵的闭包。目前,Domenic 正在与 io.js 和 v8 团队密切合作,以确保正确完成这项工作。v8 团队必须优化 promise 实现,目前本机 promise 一直输给 bluebird 等用户态实现。现在也是这样。
一旦所有这些发生,API 将被分叉,一个包含 promises 的版本将被集成到核心中。 Here is a long and uninteresting discussion 关于它 - 在 io.js/NG 存储库中有一个更好的,但两者都没有提供太多信息。
今天可以做什么
像 bluebird give you tools to instantly convert a callback API to promises 这样的库以一种快速有效的方式。您现在就可以使用它们并获得该功能。
历史上,出于性能原因,回调是默认设置,但是...
2017 年更新/节点 8:核心现在支持 Promise!
Node.js 自 Node v8.x 起支持 promises。这些 API 仍然以回调方式编写(为了向后兼容等),但是现在节点核心中有一个实用程序 class 可以将基于回调的 API 转换为基于承诺的 API(类似于 bluebird):
https://nodejs.org/api/util.html#util_util_promisify_original
来自 Node.js 文档:
For example:
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. });
Or, equivalently using async functions:
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}`); }
2018 年更新/节点 10:新 fs.promises API
fs.promises API 提供了一组替代的异步文件系统方法,return Promise 对象而不是使用回调。 API 可通过 require('fs').promises.
访问https://nodejs.org/api/fs.html#fs_fs_promises_api
(目前处于实验阶段,但在最新节点上运行完美)