如何使用 bluebird 正确地承诺 JSON.parse 方法

How to promisify correctly JSON.parse method with bluebird

我正在尝试 promisify JSON.parse 方法,但不幸的是没有任何运气。这是我的尝试:

Promise.promisify(JSON.parse, JSON)(data).then((result: any) => {...

但我收到以下错误

Unhandled rejection Error: object

首先,JSON.parse不是异步函数。所以,不要试图承诺它。


Because I want to create a chain of promises where JSON.parse stand at the top

然后,只需创建一个使用已解析的 JSON 对象解析的 Promise,就像这样

Promise.resolve(JSON.parse(data))
    .then(...)

现在,对于您的实际问题,您遇到了错误,

Unhandled rejection Error: object

因为,如果您的承诺链被拒绝,则您没有处理它。所以,不要忘记附加一个捕获处理程序,就像这样

Promise.resolve(JSON.parse(data))
    .then(...)
    .catch(...)

阅读本文 正如 Bergi 在评论中指出的那样,我在此处展示的方法存在问题。如果 JSON.parse 调用失败,则将同步抛出错误,您可能需要围绕 Promise 代码编写 try...catch。相反,人们会按照 Bergi 在 中建议的那样编写它,以创建一个仅包含数据的 Promise 对象,然后在该 Promise 链上执行 JSON.parse

Promise.promisify 被认为是采用回调函数的异步函数。 JSON.parse没有这个功能,所以你不能在这里使用promisify

如果您想从一个可能 throw 同步的函数创建一个返回承诺的函数,Promise.method 是可行的方法:

var parseAsync = Promise.method(JSON.parse);
…

parseAsync(data).then(…);

或者,您只想使用 Promise.resolve 来启动您的链:

Promise.resolve(data).then(JSON.parse).then(…);

晚会晚了,但我完全可以理解为什么您可能想要一个承诺的 JSON 从不抛出异常的解析方法。如果没有别的,那就从你的代码中删除样板 try/catch-handling 。另外,我看不出为什么同步行为不应该包含在承诺中。所以在这里:

function promisedParseJSON(json) {
    return new Promise((resolve, reject) => {
        try {
            resolve(JSON.parse(json))
        } catch (e) {
            reject(e)
        }
    })
}

用法,例如:

fetch('/my-json-doc-as-string')
  .then(promisedParseJSON)
  .then(carryOn)
  .catch(dealWithIt)