Promise 是一种异步编程解决方案,它比传统解决方案(函数和事件)更有意义且更健壮。 它最初是由社区提出并实现的,ES6 已经将其写入语言标准,统一了用法,并原生提供了 promise 对象。
Promise 对象有两个特征。
(1)物体的状态不受外界影响。
promise 对象表示异步操作有三种状态:待处理、已解决(也称为已履行)和拒绝。只有异步操作的结果才能确定它所处的状态,没有其他操作可以更改此状态。 这就是“promise”这个名字的由来,在英语中是“promise”的意思,意思是不能通过其他方式改变。
(2)状态一旦改变,就不会再改变,这个结果可以随时得到。
promise 对象只有两种可能性:从挂起到已解决,从挂起到拒绝。只要这两种情况发生,状态就会固化,不会再改变,并且会一直保持这个结果。 即使更改已经发生,您也可以向 promise 对象添加一个函数,您将立即得到此结果。 这与事件完全不同,事件的特点是,如果你错过了它并听了它,你就不会得到结果。
使用 promise 对象,您可以在同步操作流中表示异步操作,从而避免嵌套函数层。 此外,promise 对象提供了一个统一的接口,可以更轻松地控制异步操作。
承诺也有一些缺点。 首先,一个承诺是不能取消的,一旦有了新的承诺,就会立即执行,不能半途而废。 其次,如果不设置 ** 函数,promise 内部抛出的错误不会反映到外部。 第三,当处于待处理状态时,没有办法知道你目前处于哪个阶段(刚刚开始或即将结束)。
示例 1:基本用法。
var promise = new promise(function(resolve, reject) else }示例 2:一旦做出新的承诺,它将立即执行。
let promise = new promise(function(resolve, reject) )promise.then(function() console.log('hi!'); // promise // hi! // resolved示例 3:下面是使用 promise 对象实现的 AJAX 操作的示例。 (非常经典)。
var getjson = function (url) if (this.status === 200) else }return promise; }getjson("/posts.json").then(function (json) ,function (error) )promise 实例有一个 then 方法,即 then 方法在原型对象 promise 中定义原型。 它的作用是在状态更改时向 promise 实例添加一个函数。 如前所述,then 方法的第一个参数是已解析状态的函数,第二个参数(可选)是被拒绝状态的函数。
then 方法返回一个新的 promise 实例(请注意,它不是原始 promise 实例)。 因此,您可以使用链式方法,其中 then 方法后面跟着另一个 then 方法。
getjson("/posts.json").then(function(json) )then(function(post) )使用 chained then,可以指定一组按顺序调用的函数。 在这种情况下,前一个函数可能仍会返回一个 promise 对象(即存在异步操作),而后一个函数将等待 promise 对象的状态发生变化后再调用。
getjson("/post/1.json").then(function (post) )then(function funca(comments) ,function funcb(err) )在上面的第一个 then 方法中,第一个 then 方法指定的函数返回另一个 promise 对象。 在本例中,第二个 then 方法指定一个函数,该函数等待新 promise 对象的状态发生更改。 如果它被解析,它调用 funca,如果状态变为 rejected,则调用 funcb。
promise.prototype.catch 方法是。 then(null, rejection) 指定发生错误时的 ** 函数。
例:
getjson("/posts.json").then(function (posts) )catch(function (error) )与传统的 try catch 块不同,如果没有使用 catch 方法指定错误处理的函数,promise 对象抛出的错误不会传递到外层,即不会有任何反应。
var someasyncthing = function ()someasyncthing().then(function ()promise.all 方法用于将多个 promise 实例包装到一个新的 promise 实例中。
var p = promise.all([p1, p2, p3]);
以上,承诺all 方法接受数组作为参数,p1、p2 和 p3 都是 promise 对象的实例。
例:
promise.all([checklogin(),getuserinfo()]then(([res1,res2])=>, result2:$`promise.race(iterable) 方法返回一个 promise,一旦迭代器中的承诺被解析或拒绝,该 promise 就会被解析或拒绝。
有时你需要将一个现有的对象转换为一个 promise 对象,一个 promise这就是 resolve 方法的用武之地。
var jspromise = promise.resolve($.ajax('/whatever.json'));promise.reject(reason) 方法还返回一个状态为 rejected 的新 promise 实例。 它的论点与承诺的使用方式相同resolve 方法是相同的。
ES6 的 promise API 没有提供很多方法,有一些有用的方法可以自己部署。 以下是如何部署两个不属于 ES6 的有用方法。
9.1. done()promise 对象的 ** 链,无论以 then 方法还是 catch 方法结尾,如果最后一个方法抛出错误,它可能不会被捕获(因为 promise 里面的错误不会冒泡到整个世界)。 因此,我们可以提供一个 done 方法,它始终位于链的末端,并保证抛出可能发生的任何错误。
asyncfunc() then(f1) .catch(r1) .then(f2) .done();9.2. finally()finally 方法用于指定将要执行的操作,而不管 promise 对象的最终状态如何。 它与 done 方法最大的区别在于它接受一个普通的 ** 函数作为参数,无论如何都必须执行。
server.listen(0) .then(function ()finally(server.stop);生成器函数用于管理进程,当遇到异步操作时,通常会返回一个 promise 对象。
function getfoo() var g = function* (catch (e) function run(generator) ,function (error) )go(it.next())run(g);超详细的 Promise 理解与实现前端 Promise 常见应用场景正确理解 Promise 执行过程的态势 [J**Ascript]手写 Promise 必须能够深入揭开 Promise 微任务注册和执行流程的神秘面纱Promise 原理与实现超详细的 Promise 理解与实现前端 Promise 常见应用场景正确理解 Promise 执行过程的态势【J** ascript】一定能够要编写手写承诺,请添加:承诺allsettled()
直接参考文档: