JavaScript承诺概述

本教程涵盖了JavaScript Promise的基础知识,展示了如何在JavaScript开发中利用它们。

Promise的概念对于Web开发而言并不是新事物。 我们中的许多人已经以诸如Q,when.js,RSVP.js之类的库的形式使用了Promise。甚至jQuery都有一个称为Deferred对象的东西,它类似于Promise。 但是现在我们已经对JavaScript中的Promise提供了本机支持,这确实令人兴奋。

总览

Promise对象表示一个可能尚不可用的值,但将来会在某个时候解析它。 它允许您以更同步的方式编写异步代码。 例如,如果您使用Promise API对远程Web服务进行异步调用,则将创建Promise对象,该对象表示将来Web服务将返回的数据。 需要注意的是,实际数据尚不可用。 当请求完成并且Web服务返回响应时,它将变为可用。 同时, Promise对象就像是实际数据的代理。 此外,您可以将回调附加到Promise对象,一旦实际数据可用,就会调用该回调。

API

首先,让我们检查以下代码,该代码创建一个新的Promise对象:

const promise = new Promise((resolve, reject) => {
  //asynchronous code goes here
});

我们先实例化一个新的Promise对象,然后将其传递给回调函数。 回调函数有两个参数, resolvereject ,它们都是函数。 您所有的异步代码都放在该回调中。 如果一切成功,则通过调用resolve()实现诺言。 发生错误时,将使用Error对象调用reject() 。 这表明诺言被拒绝了。

现在,让我们构建一些简单的方法来显示如何使用promise。 以下代码向Web服务发出异步请求,该请求以JSON格式返回随机笑话。 让我们研究一下如何使用诺言:

const promise = new Promise((resolve, reject) => {
  const request = new XMLHttpRequest();

  request.open('GET', 'https://api.icndb.com/jokes/random');
  request.onload = () => {
    if (request.status === 200) {
      resolve(request.response); // we got data here, so resolve the Promise
    } else {
      reject(Error(request.statusText)); // status is not 200 OK, so reject
    }
  };

  request.onerror = () => {
    reject(Error('Error fetching data.')); // error occurred, reject the  Promise
  };

  request.send(); // send the request
});

console.log('Asynchronous request made.');

promise.then((data) => {
  console.log('Got data! Promise fulfilled.');
  document.body.textContent = JSON.parse(data).value.joke;
}, (error) => {
  console.log('Promise rejected.');
  console.log(error.message);
});

在前面的代码中, Promise构造函数回调包含用于从远程服务获取数据的异步代码。 在这里,我们仅向https://api.icndb.com/jokes/random创建一个Ajax请求,该请求将返回一个随机笑话。 从远程服务器接收到JSON响应后,该响应将传递到resolve() 。 发生任何错误时,将使用Error对象调用reject()

实例化Promise对象时,我们获得了将来将可用的数据的代理。 就我们而言,我们希望将来某个时候从远程服务返回一些数据。 那么,我们如何知道数据何时可用? 这是使用Promise.then()函数的地方。 该函数有两个参数:成功回调和失败回调。 在Promise结算(即实现或拒绝)时调用这些回调。 如果实现了诺言,则将使用传递给resolve()的实际数据触发成功回调。 如果承诺被拒绝,则将调用失败回调。 您传递给reject()都将作为参数传递给此回调。

试试这个CodePen示例。 要查看新的随机笑话,请点击嵌入右下角的RERUN按钮。 另外,打开浏览器控制台,以便您可以看到执行代码不同部分的顺序。

请参阅PenP上的SitePoint@SitePoint的JavaScript承诺概述

请注意,promise可以具有三种状态:

  • 待处理(未实现或拒绝)
  • 完成
  • 被拒绝

Promise.status属性是代码不可访问的私有属性,它提供有关这些状态的信息。 一旦诺言被拒绝或实现,此状态便会与之永久关联。 这意味着一个承诺只能成功或失败一次。 如果Promise已被兑现,然后您通过两个回调将then()附加到它上,则将成功调用成功回调。 因此,在承诺的世界中,我们对知道何时兑现承诺不感兴趣。 我们只关心承诺的最终结果。

连锁承诺

有时希望将承诺链接在一起。 例如,您可能要执行多个异步操作。 当一个操作为您提供数据时,您将开始对该数据块执行其他操作,依此类推。 可以将承诺链接在一起,如以下示例所示:

function getPromise(url) {
  // return a Promise here
  // send an async request to the url as a part of promise
  // after getting the result, resolve the promise with it
}

const promise = getPromise('some url here');

promise.then((result) => {
  //we have our result here
  return getPromise(result); //return a promise here again
}).then((result) => {
  //handle the final result
});

棘手的部分是,当您在then()内部返回一个简单值时,将使用该返回值调用下一个then() 。 但是,如果您在then()内部返回一个诺言,则下一个then()在其上等待并在该诺言得到解决时被调用。

处理错误

您已经知道then()函数将两个回调作为参数。 如果诺言被拒绝,将调用第二个。 但是我们还有一个catch()函数,可用于处理承诺拒绝。 看下面的代码:

promise.then((result) => {
  console.log('Got data!', result);
}).catch((error) => {
  console.log('Error occurred!', error);
});

这等效于:

promise.then((result) => {
  console.log('Got data!', result);
}).then(undefined, (error) => {A
  console.log('Error occurred!', erroAr);
});

请注意,如果Promise被拒绝并且then()没有失败回调,则控件将通过失败回调或下一个catch()前进到下一个then() catch() 。 除了显式的promise拒绝之外,当从Promise构造函数回调中引发任何异常时,还会调用catch() 。 因此,您也可以将catch()用于记录目的。 请注意,我们可以使用try...catch来处理错误,但是对于promises来说并不是必须的,因为任何异步或同步错误总是由catch()

结论

这只是JavaScript的新Promises API的简要介绍。 显然,它使我们可以非常轻松地编写异步代码。 我们可以像往常一样进行操作,而无需知道将来异步代码将返回什么值。 关于API的更多内容未在此处介绍。 要了解有关Promises的更多信息,请查看我的后续文章A Deep Dive Into JavaScript Promises以及以下重要资源:

From: https://www.sitepoint.com/overview-javascript-promises/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值