首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Javascript :承诺链还是异步/等待?

Javascript :承诺链还是异步/等待?
EN

Stack Overflow用户
提问于 2018-05-07 22:21:55
回答 2查看 9.2K关注 0票数 14

我正在学习Javascript Promiseasync/await。下面的示例代码异步读取和解析node.js中的JSON文件(my node.js版本为v10.0.0)。

在示例代码中,ChainReadJson函数和AwaitReadJson函数进行相同的操作,读取和解析JSON文件。区别在于ChainReadJson函数使用承诺链,而AwaitReadJson函数使用异步/等待。

代码语言:javascript
运行
复制
const FS = require("fs");

function ReadFile(fileName) {
    return new Promise((Resolve, Reject) => {
        FS.readFile(fileName, 'utf8', (error, result) => {
            if (error)
                Reject(error);
            else
                Resolve(result);
        });
    });
}

// function using promise chain

function ChainReadJson(fileName, CallBack) {
    ReadFile(fileName)
        .then(
            res => JSON.parse(res),
            err => {
                Message(-1, err.message);
            }
        )
        .then(
            res => {
                if (res !== undefined)
                    CallBack(fileName, res);
            },
            err => {
                Message(-2, err.message);
            }
        );
}

// function using async/await

async function AwaitReadJson(fileName, CallBack) {
    let res, json;

    try {
        res = await ReadFile(fileName);
    }
    catch (err) {
        Message(-1, err.message);
        return;
    }
    try {
        json = JSON.parse(res);
    }
    catch (err) {
        Message(-2, err.message);
        return;
    }
    CallBack(fileName, json);
}

ChainReadJson('test.json', PrintJSON);
AwaitReadJson('test.json', PrintJSON);

// common functions

function PrintJSON(fileName, json) {
    console.log(`JSON[${fileName}]:`, json);
}

function Message(n, str) {
    console.log(`[${n}]`, str);
}

在使用允诺链为ChainReadJson函数编写代码时,我很难控制执行结果和错误。然而,当使用异步/等待为AwaitReadJson函数编写代码时,这些困难大多消失了。

我是否正确理解异步/等待的好处?异步/等待与承诺链相比有什么缺点?

(示例代码是这个答案中的代码的修改版本。原始代码只使用允诺链,编写这些代码是为了准确地知道在链中错误发生的位置和错误是什么)

EN

回答 2

Stack Overflow用户

发布于 2018-05-07 22:56:10

实际上,与回调、承诺和生成器函数相比,async/await是减少样板和使异步程序更容易编写的设计

  • 虽然承诺是以相同的目标创建的,但它们还有一个额外的限制,即必须在现有的JS引擎中工作--因此它们的语法更加复杂。使用异步/等待的需要一个,如果您正在编写自己的node.js应用程序,可能并不重要,但是库可能需要与较旧的node.js版本兼容(我不确定是否可以在不支持生成器的情况下将其移植到旧的浏览器中使用)。
  • 由于异步/等待是较新的,所以并不像优化的那样。去年的报告蓝鸟承诺(一个JS库实现了简化版本的承诺)在某个基准测试中的性能优于异步/等待。(当然,当您的用例发出一些网络请求时,这可能并不重要。)
  • 您仍然可以需要承诺并行执行多个异步操作。 (编辑:如果您需要他们的结果)
票数 12
EN

Stack Overflow用户

发布于 2018-05-08 16:36:50

虽然async/await可能是清理异步逻辑的好方法,但值得指出的是,可以显着地清理承诺逻辑,这一点非常类似于异步/等待选项:

代码语言:javascript
运行
复制
const fs = require("fs");
const util = require("util")

//Could also use the experimental "fs/promise" api from node v10
const promisifiedReadFile = util.promisify(fs.readFile);

const readFile = (fileName) => promisifiedReadFile(fileName, 'utf8');

function chainReadJson(fileName, callback) {
    return readFile(fileName)
        .then(json => JSON.parse(json))
        .then(result => callback(null, result))
        .catch(e => {
            console.log("Error reading or parsing file", e.message);
            callback(e)
        });
}

这里唯一的功能区别是,所有的错误日志记录都发生在一个地方,在链的末尾。

为readFile和JSON.parse保留拆分日志是可能的,但这显然有点棘手。您通常希望在处理错误后重新抛出错误,以便跳过下游.then处理程序:但是如果再次抛出错误,下游.catch处理程序将再次捕获错误,如果您找不到过滤的方法,这将导致重复日志记录。

这是可行的,但有点痛苦,所以我把它排除在上面的代码之外。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50223295

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档