javascript - Nodejs 对方法或 promise 的回调?

标签 javascript node.js asynchronous

我是 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/

相关文章:

node.js - 如何使用 websockets 连接两个 node.js 服务器?

c# - 在异步 ASP.Net 页面中处理来自异步任务的错误

c# - 如何在计时器中使用异步和等待

javascript - AngularJS 中的 $injector.unpr 错误

javascript - PHP,Jquery(ajax) post uncaught syntaxerror :unexpected token <

javascript - 获取Node.js中文件中的所有函数

node.js - 完成所有迭代后的 async.each 回调

javascript - 为什么 jQuery 的 .change() 事件仅在单击鼠标右键时触发?

javascript - 疯狂的 javascript 问题 : undefined actually ! == 未定义!

json - 解析扭曲数据接收中的数据