📌  相关文章
📜  如何从 JavaScript 中的异步调用返回响应?

📅  最后修改于: 2022-05-13 01:56:51.829000             🧑  作者: Mango

如何从 JavaScript 中的异步调用返回响应?

JavaScript 是一种单线程编程语言,异步编程是构建该语言的基本概念。 JavaScript 内置了三种处理异步调用的方法,如下所示:

  • 回调函数
  • 使用 .then() 和 .catch() 方法进行 Promise 和 Promise 处理
  • 使用 await 的 ES6+/ESNext 风格的异步函数

在本文中,我们将讨论如何以上述所有方式处理异步调用。我们将使用 Node.js 中提供的请求模块从网站 DOG CEO API 请求 JSON 数据,该 API 返回 JSON 格式的随机狗图片的 URL 链接。

  1. 使用回调函数:
    // Callback method
    const request = require('request');
    const url ='https://dog.ceo/api/breeds/image/random';
      
    function callback(res, body) { 
        console.log(JSON.parse(body));
    }
      
    function getData(callback) {
      
        // Using the request module to request
        // data asynchronously
        request(url, (err, res, body) => {
            if (err) throw err;
            callback(res, body);
        });
    }
      
    // Here we call the getData function
    // with the callback function 
    getData(callback);
    console.log('asynchronous is awesome');
    

    输出:

    asynchronous is awesome {
      message: 
    'https://images.dog.ceo/breeds/vizsla/n02100583_11450.jpg',  
      status: 'success'
    }
    

    说明:在这个方法中,我们请求 JSON 数据的 API,并使用回调函数对数据执行函数。为了便于理解,我们只是将接收到的数据记录到控制台,但可以执行各种其他功能。这整个过程是异步发生的。命令console.log('asynchronous is awesome');虽然放置在对函数getData 的调用之后,但在 getData 完成之前执行。

  2. 将 Promises 与 .then() 和 .catch() 方法一起使用:
    // Promise with then catch
    const promise = new Promise((resolve, reject) => {
        request(url, (err, res, body) => {
            if (err) return reject(err);
            try {
                resolve(JSON.parse(body));
            } catch(error) {
                reject(error);
            }
        });
    });
      
    promise.then((data) => {
        console.log(data);
    })
    .catch((err)=>{
        console.error(err);
    });
      
    console.log('asynchronous is awesome');
    

    输出:

    asynchronous is awesome {
      message:
    'https://images.dog.ceo/breeds/pointer-germanlonghair/hans2.jpg',
      status: 'success'
    }
    

    说明:请求模块本身不返回承诺。因此,我们使用 Promise 构造函数将从 HTTP 请求接收到的可能响应包装到本机 Promise 中。然后使用 .then() 和 .catch() 方法处理此承诺。使用这种方法的优点是多方面的。首先,使用 .then() 和 .catch() 方法解决 Promise 是错误处理的最佳实践,有助于我们以错误优先的心态编写代码。其次,JavaScript 模块正在适应支持 Promise 并丢弃旧的回调样式错误处理。 Axios、fetch 等较新的模块仅支持 Promise。同样,Promises 是一种相对较新的异步代码编写方式。命令console.log('asynchronous is awesome');证明了这一点。虽然放置在对 promise 处理程序的调用之后,但在 promise 完成之前执行。

  3. 使用 await 的 ES6+/ESNext 风格的异步函数:
    const getData = async () => {
        let data = await new Promise((resolve, reject) => {
            request(url, (err, res, body) => {
                if (err) return reject(err);
                try{
                    resolve(JSON.parse(body));
                } catch(error) {
                    reject(error);
                }
            });
        });
      
        try{
            console.log(data);
        }
        catch(err){
            console.error(err);
        }
    }
      
    getData();
    console.log('asynchronous is best');
    

    输出:

    asynchronous is awesome {
      message: 
    'https://images.dog.ceo/breeds/sheepdog-shetland/n02105855_15196.jpg',
      status: 'success'
    }
    

    说明: Javascript 中的异步函数允许我们坚持传统的编程策略,例如使用 for、while 和其他本质上是同步的并且不能在 Javascript 中使用的方法。在此示例中,我们将 HTTP 请求返回的可能响应包装在一个 Promise 中。由于 promise 需要一定的时间来解决或拒绝,我们使用 await 关键字来等待 promise 返回响应。最佳实践是使用 try()/catch() 序列来处理使用 await 后从 Promise 收到的响应,以帮助我们处理错误(如果有)。虽然同步代码可以写在 try()/catch() 序列中,但是 async函数是异步执行的,这一点可以通过命令console.log('asynchronous is awesome');来证明。虽然放置在对函数getData 的调用之后,但在异步函数完成之前执行。