在书https://pragprog.com/book/tbajs/async-javascript中,我发现了这一点:
Node的早期迭代在其非阻塞API中使用了Promises。然而, 2010年2月,瑞安达尔决定改用 现在熟悉的回调(错误,结果......)格式,理由是 Promise是属于“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是一个更高层次的构造"会阻止自己在NodeJS API中使用吗?
答案 0 :(得分:15)
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的承诺。事实上,目前正在讨论如何。由于摩擦和性能问题,多年前在节点中使用Promise的早期尝试失败了。
现在promises是一种本地语言功能,但必须在它们进入核心API之前发生:
一旦发生所有这些,API将被分叉,并且包含promises的版本将被集成到核心中。 Here is a long and uninteresting discussion关于它 - 在io.js / NG回购中有一个更好的,但两者都没有太多的信息。
像bluebird这样的图书馆以快速有效的方式为您提供即时convert a callback API to promises的工具。您今天可以使用它们并获得该功能。
答案 1 :(得分:4)
历史上,回调是性能原因的默认值,但是......
更新2017 /节点8:核心现在支持Promise!
Node.js支持自Node v8.x以来的promise。 API仍然以回调方式编写(为了向后兼容等),但现在节点核心中有一个实用程序类,用于将基于回调的API转换为基于promise的API(类似于bluebird):
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. });
或者,等效地使用异步函数:
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}`); }
答案 2 :(得分:3)
更新2018年/节点10:新的fs.promises API
fs.promises API提供了一组备用的异步文件系统方法,它们返回Promise对象而不是使用回调。 API可通过require('fs')。promises。
访问https://nodejs.org/api/fs.html#fs_fs_promises_api
(此时为实验,但最新节点上工作正常)
答案 3 :(得分:-4)
Promises是一个库,当使用promise时,它需要从函数返回Promise构造函数,但是使用回调函数链接相同的东西是可以实现的,这就是为什么" Promises是一个更高级别的构造"