我是 Node 新手,我看到我的应用程序中出现了回调 hell 模式,这使得它难以阅读。
经过一番研究,互联网给出了 2 个主要解决方案:
-导出函数
转动这个:
var fs = require('fs');
var myFile = '/tmp/test';
fs.readFile(myFile, 'utf8', function(err, txt) {
if (err) return console.log(err);
txt = txt + '\nAppended something!';
fs.writeFile(myFile, txt, function(err) {
if(err) return console.log(err);
console.log('Appended text!');
});
});
进入此:
var fs = require('fs');
function notifyUser(err) {
if(err) return console.log(err);
console.log('Appended text!');
};
function appendText(err, txt) {
if (err) return console.log(err);
txt = txt + '\nAppended something!';
fs.writeFile(myFile, txt, notifyUser);
}
var myFile = '/tmp/test';
fs.readFile(myFile, 'utf8', appendText);
和 使用 Promise
我更倾向于函数的导出,但互联网上说 Promise 是处理异步调用的更好选择。
我不想进入某些事情,以后必须改变我的编码习惯/风格以符合标准约定,最好从正确的道路开始。
那么我应该开始使用 Promise 还是导出函数是一个很好的解决方案?
最佳答案
你现在有第三个选择,这可能会超出纯粹意见的范围:Promises + async
/await
:
ES2017(6 月发布的规范)将采用 async
/await
功能,它们为简单用例中的消费 Promise 提供更简单的语法,NodeJS 已经在Node v7 的当前版本(撰写本文时为 v7.7.2)。
使用 Promise 和 async
/await
,您的代码将如下所示:
const p = require(/*...some theoretical promisifier...*/).promisifier;
const fs = require('fs');
async function go() {
const myFile = '/home/tjc/temp/test';
let txt = await p(fs.readFile, myFile, 'utf8');
txt = txt + '\nAppended something!';
await p(fs.writeFile, myFile, txt);
console.log('Appended text!');
}
go().catch(error => {
console.log(error);
});
它仍然是异步的,只是简单 Promise 用例的语法更简单,允许您让代码反射(reflect)逻辑,而无需中间 then
回调函数。
请注意,您只能在 async
函数中使用 await
(因为它们在幕后管理 Promise)。另请注意,NodeJS 很快就会对未处理的 Promise 拒绝感到骄傲,因此请确保我们在 go()
上执行 catch
。
我相信上面的内容大致可以转换为以下内容:
const p = require(/*...some theoretical promisifier...*/).promisifier;
const fs = require('fs');
function go() {
const myFile = '/home/tjc/temp/test';
return p(fs.readFile, myFile, 'utf8').then(txt => {
txt = txt + '\nAppended something!';
return p(fs.writeFile, myFile, txt).then(() => {
console.log('Appended text!');
});
});
}
go().catch(error => {
console.log(error);
});
...但是当然,如果您自己编写它,您会以不同的方式组织它:
const p = require(/*...some theoretical promisifier...*/).promisifier;
const fs = require('fs');
function go() {
const myFile = '/home/tjc/temp/test';
return p(fs.readFile, myFile, 'utf8')
.then(txt => {
txt = txt + '\nAppended something!';
return p(fs.writeFile, myFile, txt);
})
.then(() => {
console.log('Appended text!');
});
}
go().catch(error => {
console.log(error);
});
正如您所看到的,就清晰度而言,async
/await
为简单的用例带来了很多好处。 (对于更复杂的用例,您仍然必须回退到显式的 Promise 处理。)
不过,这是否能让我们脱离观点的范畴,则是另一个问题了。当然,无论您是否使用 Promise,保持函数较小且可组合是一件好事。
<小时/>关于上面的p
:有各种库可用于使用 Node 的标准回调机制编写的 promise API;在上面我使用的是理论的。这是上面 p
的一个非常非常简单的实现:
const p = (f, ...args) => {
return new Promise((resolve, reject) => {
args.push((err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
});
f(...args);
});
};
exports.promisifier = p;
...但是您可以找到采用更彻底方法的库。
关于javascript - Nodejs 对方法或 promise 的回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42735948/