【问题标题】:Understanding promises in node js?理解节点 js 中的承诺?
【发布时间】:2019-06-14 14:43:50
【问题描述】:

我正在学习node js中的promise。我写了一段代码如下。

var request = require("request");
var userDetails;

function getData(url) {
    // Setting URL and headers for request
    var options = {
        url: url,
        headers: {
            'User-Agent': 'request'
        }
    };
    // Return new promise 
    return new Promise(function (resolve, reject) {
        // Do async job
        request.get(options, function (err, resp, body) {
            if (err) {
                reject(err);
            } else {
                resolve(body);
            }
        })
    })
}

var errHandler = function (err) {
    console.log(err);
}

function main() {
    var userProfileURL = "https://api.githshub.com/users/narenaryan";
    var dataPromise = getData(userProfileURL);
    // Get user details after that get followers from URL
    var whichPromise = dataPromise.then(JSON.parse)
        .then(function (result) {
            userDetails = result;
            // Do one more async operation here
            console.log("then1")
            var anotherPromise = getData(userDetails.followers_url).then(JSON.parse);
            return anotherPromise;
        })
        .then(function (data) {
            return data
        });
    console.log(whichPromise)

    whichPromise.then(function (result) {
        console.log("result is" + result)

    }).catch(function (error) {
        console.log("Catch" + error)
    });
}


main();

现在这工作得很好。我有这方面的疑问。

1. JSON.Parse 如何在不获取 json 字符串的情况下解析数据。

var whichPromise = dataPromise.then(JSON.parse)

2.如果我在下面的行中输入了错误的 url

var userProfileURL = "https://api.githshub.com/users/narenaryan";

然后阻止将不起作用,因为 DNS 将无法解析并且应该得到一个错误,这意味着

 var anotherPromise = getData(userDetails.followers_url).then(JSON.parse);
            return anotherPromise;

不会返回任何值,whichPromise 不会有任何引用。

但是如果调用下面的代码

whichPromise.then(function (result) {
        console.log("result is" + result)

    }).catch(function (error) {
        console.log("Catch" + error)
    });

这里 whichPromise 能够调用 catch 块。有人能解释一下为什么吗?

【问题讨论】:

  • 你只是将JSON.parse函数作为参数传递,见this,它类似于写.then(x => JSON.parse(x)),每个promise都应该在then链的末尾包含一个catch块
  • 如果你输入了错误的url,就会出现错误if (err) {reject(err); },所以whichPromise 可以调用catch块。 IMO 拒绝像 throw error 这样的工作,但在异步回调中,您必须使用拒绝而不是 throw error

标签: node.js promise es6-promise node-modules


【解决方案1】:

JSON.Parse 如何在不获取 json 字符串的情况下解析数据。

var whichPromise = dataPromise.then(JSON.parse)

.then() 期望你向它传递一个函数。当 Promise 解析时,它将调用该函数并将 Promise 的解析值传递给它。

所以,您将JSON.parse 函数传递给它,然后它会调用该函数并将promise 的结果值传递给它,这将是您的JSON 字符串。执行该函数的返回值将成为链中结果承诺的解析值。因此,在您的情况下,JSON.parse() 返回的 Javascript 对象成为您的承诺链的解析值。

如果我在...中输入了错误的 URL

错误的 URL 显然不会获取您想要的数据。根据错误的 URL,它会产生网络错误(例如解析主机的 DNS 错误)或返回 404 错误(该主机上没有这样的路径),或者服务器可能会返回一些其他类型的响应。从request.get() 返回的确切内容取决于您传递给request.get() 的选项以及URL 到底是如何错误的。在某些情况下,promise 将被拒绝,在这种情况下,您的 .then() 处理程序将不会被调用。在其他情况下,promise 可能仍然会得到解决,但不会有数据或不正确的 JSON 传递给JSON.parse() 结果是一些其他错误。

重要的是要了解,当您发送带有 http 请求的无效路径时,返回 404 响应代码不会被许多库视为 http 错误。你到达了服务器,你向它发送了一个请求,它处理了那个请求并返回了一个响应。尽管响应可能是 404 状态代码,但这不一定被视为错误。因此,您自己的代码必须配置您使用的 http 库以强制 404 或任何 4xx 成为错误,或者您必须明确检查以正确处理它。

【讨论】:

  • 我理解如果我的 URL 错误的后果以及原因,但仍然感谢您的解释。我想知道为什么会调用 catch 块,因为 whichPromise 可能没有引用,因为 then 块没有执行。我故意弄错了 URL,以便可以执行 catch 块。
  • @DhirajKumar - 如果getData() 拒绝,那么dataPromise 将是一个被拒绝的承诺,dataPromise.then() 将是一个被拒绝的承诺,这意味着whichPromise 将是一个被拒绝的承诺,因此它将触发.catch() 处理程序。如果 getData() 解析为不是 JSON 的数据,则 JSON.parse(badData) 将被调用,并且 whichPromise 仍将最终被拒绝,因此它将触发其 .catch() 处理程序。不知道你还问什么。
【解决方案2】:

让我们尝试一步一步地理解它。

1

=> dataPromise.then(JSON.parse)

这就等于写了

=> dataPromise.then(data => JSON.parse(data))

因为,JSON.parse 是一种将一些数据(字符串)作为第一个输入并返回解析后的 JS-Object 的方法。但是,在清晰的画面中,它是一个纯函数。

在第二行我做了什么来清除你的概念我传递了匿名箭头函数,它也是一个 arg(数据)作为第一个 arg 并返回 JS.parse() 方法返回的内容。 因此,我们正在创建一个额外的层或执行上下文。那个额外的上下文被称为“点”

=> dataPromise.then(data => JSON.parse(data)) with-extra function layer

=> dataPromise.then(JSON.parse) 直接传递 JSON.parse (arg => parsedObj)

这个示例官方软件词汇被称为“无点编程”。

【讨论】:

  • 感谢您的解释。你也能回答2分吗?
猜你喜欢
  • 2018-09-26
  • 2015-02-22
  • 2016-09-08
  • 1970-01-01
  • 2017-07-23
  • 1970-01-01
  • 2018-10-11
  • 2017-09-06
  • 1970-01-01
相关资源
最近更新 更多