您的当前位置:首页正文

Javascript Promise用法详解

2023-12-08 来源:站点网
导读promise的作用:ajax是异步请求,多层嵌套会造成回调地狱,promise模拟同步,将异步回调类似于同步来处理业务逻辑。var p = new Promise(function(){//这里用于处理异步的回调}),必传回调函数,不传程序会抛出异常。创建实例对象时,回调函数会立即执行。promise的三种状态:pending:正在进行状态fulfilled:完成状态rejected:失败状态传参1 resolve,是个函数,只要这个函数执行了说明是成功状态,参数2选传,rejecte,是个函

或许你会问,这个操作明明是同步的,定义 Promise 里面的代码都被立即执行了,那么回调应该紧接着 resolve 函数执行,那么应该先打印 “resolved” 而不应该先打印 “end Promise”.

这个是 Promise 规范规定的,为了防止同步调用和异步调用同时存在导致的混乱

6、Promise 的链式调用(连贯操作)

前面我们讲过,Promise 的 then 方法以及 catch 方法返回的都是新的 Promise 对象,这样我们可以非常方便的解决嵌套的回调函数的问题, 也可以很方便的实现流程任务。

var p = new Promise(function(resolve, reject) { resolve();});function taskA() { console.log("Task A");}function taskB() { console.log("Task B");}function taskC() { console.log("Task C");}p.then(taskA()).then(taskB()).then(taskC()).catch(function(error) { console.log(error);});

上面这段代码很方便的实现了从 taskA 到 taskC 的有序执行。

当然你可以把 taskA - taskC 换成任何异步操作,如从后台获取数据:

var getJSON = function(url, param) { var promise = new Promise(function(resolve, reject){ var request = require('ajax-request'); request({url:url, data: param}, function(err, res, body) { if (!err && res.statusCode == 200) { resolve(body); } else { reject(new Error(err)); } }); }); return promise;};var url = "login.php";getJSON(url, {id:1}).then(result => { console.log(result); return getJSON(url, {id:2})}).then(result => { console.log(result); return getJSON(url, {id:3});}).then(result => { console.log(result);}).catch(error => console.log(error));

这样用起来似乎很爽,但是有个问题需要注意,我们说过每个 then() 方法都返回一个新的 Promise 对象,那既然是 Promise 对象,那肯定就有注册 onFulfilled 和 onRejected, 如果某个任务流程的 then() 方法链过长的话,前面的任务抛出异常,会导致后面的任务被跳过。

function taskA() { console.log("Task A"); throw new Error("throw Error @ Task A");}function taskB() { console.log("Task B");}function onRejected(error) { console.log(error);}function finalTask() { console.log("Final Task");}var promise = Promise.resolve();promise .then(taskA) .then(taskB) .catch(onRejected) .then(finalTask);

执行的结果是:

Task AError: throw Error @ Task AFinal Task

显然, 由于 A 任务抛出异常(执行失败),导致 .then(taskB) 被跳过,直接进入 .catch 异常处理环节。

6.1 promise chain 中如何传递参数

上面我们简单阐述了 Promise 的链式调用,能够非常有效的处理异步的流程任务。

但是在实际的使用场景中,任务之间通常都是有关联的,比如 taskB 需要依赖 taskA 的处理结果来执行,这有点类似 Linux 管道机制。 Promise 中处理这个问题也很简单,那就是在 taskA 中 return 的返回值,会在 taskB 执行时传给它。

function taskA() { console.log("Task A"); return "From Task A";}function taskB(value) { console.log(value); console.log("Task B"); return "From Task B";}function onRejected(error) { console.log(error);}function finalTask(value) { console.log(value); console.log("Final Task");}var promise = Promise.resolve();promise .then(taskA) .then(taskB) .catch(onRejected) .then(finalTask);

搞定,就这么简单!

6.2 resolve 和 reject 参数

reject函数的参数通常是Error对象的实例,表示抛出的错误;resolve函数的参数除了正常的值以外,还可能是另一个 Promise 实例, 比如像上面的 getJSON() 方法一样。

var p1 = new Promise(function (resolve, reject) { setTimeout(() => reject(new Error('fail')), 3000)})var p2 = new Promise(function (resolve, reject) { setTimeout(() => resolve(p1), 1000)})p2 .then(result => console.log(result)) .catch(error => console.log(error))

注意,这时p1的状态就会传递给p2,也就是说,p1的状态决定了p2的状态。

如果p1的状态是 pending,那么p2的回调函数就会等待p1的状态改变;

如果p1的状态已经是 resolved 或者 rejected,那么p2的回调函数将会立刻执行。

7、Promise 基本方法

ES6的Promise API提供的方法不是很多,下面介绍一下 Promise 对象常用的几个方法.

7.1 Promise.prototype.catch()

Promise.prototype.catch方法是.then(null, rejection)的别名,用于指定发生错误时的回调函数。

p.then((val) => console.log('fulfilled:', val)) .catch((err) => console.log('rejected', err));// 等同于p.then((val) => console.log('fulfilled:', val)) .then(null, (err) => console.log("rejected:", err));

Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获。 所以通常建议使用 catch 方法去捕获异常,而不要用 then(null, function(error) {}) 的方式,因为这样只能捕获当前 Promise 的异常

p.then(result => {console.log(result)}) .then(result => {console.log(result)}) .then(result => {console.log(result)}) .catch(error => { //捕获上面三个 Promise 对象产生的异常 console.log(error); });

跟传统的try/catch代码块不同的是,如果没有使用catch方法指定错误处理的回调函数,Promise 对象抛出的错误不会传递到外层代码,即不会有任何反应。

通俗的说法就是“Promise 会吃掉错误”。

比如下面的代码就出现这种情况

var p = new Promise(function(resolve, reject) { // 下面一行会报错,因为x没有声明 resolve(x + 2); });p.then(() => {console.log("every thing is ok.");});// 这行代码会正常执行,不会受 Promise 里面报错的影响console.log("Ok, it's Great.");

7.2 Promise.all()

Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。用来处理组合 Promise 的逻辑操作。

var p = Promise.all([p1, p2, p3]); 

上面代码 p 的状态由p1、p2、p3决定,分成两种情况。

  1. 只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
  2. 只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

下面是一个具体的例子

// 生成一个Promise对象的数组var promises = [1,2,3,4,5,6].map(function (id) { return getJSON('/post/' + id + ".json");});Promise.all(promises).then(function (posts) { // ...}).catch(function(reason){ // ...});

上面代码中,promises 是包含6个 Promise 实例的数组,只有这6个实例的状态都变成 fulfilled,或者其中有一个变为 rejected, 才会调用 Promise.all 方法后面的回调函数。

7.3 Promise.race()

Promise.race方法同样是将多个Promise实例,包装成一个新的Promise实例。 与 Promise.all 不同的是,只要有一个 promise 对象进入 FulFilled 或者 Rejected 状态的话,Promise.rece 就会继续进行后面的处理

var p = Promise.race([p1, p2, p3]);

上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。 Promise.race 方法的参数与 Promise.all 方法一样,如果不是 Promise 实例,就会先调用 Promise.resolve 方法, 将参数转为 Promise 实例,再进一步处理。

下面是一个具体的例子

// `delay`毫秒后执行resolvefunction timerPromisefy(delay) { return new Promise(function (resolve) { setTimeout(function () { resolve(delay); }, delay); });}// 任何一个promise变为resolve或reject 的话程序就停止运行Promise.race([ timerPromisefy(1), timerPromisefy(32), timerPromisefy(64), timerPromisefy(128)]).then(function (value) { console.log(value); // => 1});

7.4 Promise.resolve()

Promise.resolve 方法有2个作用,一个就是前面我们说的,它是通过静态方法创建 Promise 实例的渠道之一, 另一个作用就是将 Thenable 对象转换为 Promise 对象。

那么什么是 Thenable 对象呢?ES6 Promises里提到了Thenable这个概念,简单来说它就是一个非常类似promise的东西。 就像我们有时称具有 .length 方法的非数组对象为 Array like 一样,Thenable 指的是一个具有 .then 方法的对象。

这种将 Thenable对象转换为 Promise 对象的机制要求thenable对象所拥有的 then 方法应该和Promise所拥有的 then 方法具有同样的功能和处理过程, 在将 Thenable 对象转换为 Promise 对象的时候,还会巧妙的利用 Thenable 对象原来具有的 then 方法。

到底什么样的对象能算是 Thenable 的呢,最简单的例子就是 jQuery.ajax(),它的返回值就是 Thenable 的。

将 Thenable 对象转换为 Promise 对象

var promise = Promise.resolve($.ajax('/json/comment.json'));// => promise对象promise.then(function(value){ console.log(value);});

除了上面的方法之外,Promise.resolve方法的参数还有以下三种情况。

(1). 参数是一个 Promise 实例

如果参数是Promise实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例。

(2). 参数不是具有then方法的对象,或根本就不是对象

如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的Promise对象,状态为resolved。

var p = Promise.resolve('Hello');p.then(function (s){ console.log(s)});

上面代码生成一个新的Promise对象的实例p。由于字符串Hello不属于异步操作(判断方法是字符串对象不具有then方法), 返回Promise实例的状态从一生成就是resolved,所以回调函数会立即执行。 Promise.resolve方法的参数,会同时传给回调函数。

(3). 不带有任何参数

Promise.resolve方法允许调用时不带参数,直接返回一个resolved状态的Promise对象。这个我们在上面讲创建 Promise 实例的三种方法的时候就讲过了

var p = Promise.resolve();p.then(function () { // ...});

7.5 Promise.reject()

Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected。 需要注意的是,Promise.reject()方法的参数,会原封不动地作为 reject 的理由,变成后续方法的参数。这一点与 Promise.resolve 方法不一致。

const thenable = { then(resolve, reject) { reject('出错了'); }};Promise.reject(thenable).catch(e => { console.log(e === thenable)})// true

上面代码中,Promise.reject 方法的参数是一个 thenable 对象,执行以后,后面 catch 方法的参数不是 reject 抛出的“出错了”这个字符串, 而是 thenable 对象。

小编还为您整理了以下内容,可能对您也有帮助:

JS中promise对象的作用与使用

promise的作用:ajax是异步请求,多层嵌套会造成回调地狱,promise模拟同步,将异步回调类似于同步来处理业务逻辑。
var p = new Promise(function(){
//这里用于处理异步的回调

}),必传回调函数,不传程序会抛出异常。
创建实例对象时,回调函数会立即执行。
promise的三种状态:
pending:正在进行状态
fulfilled:完成状态
rejected:失败状态
传参1 resolve,是个函数,只要这个函数执行了说明是成功状态,参数2选传,rejecte,是个函数,这个函数执行了说明是失败状态。这两个只能执行一个,变化不可逆。
promise两种结果:
从进行到失败
从进行到成功
通过rejecte(data)h或者resolve(data)将异步响应的数据提取出来,在promise外部使用。
promise的then方法,用于处理成功或者失败的回调。
//接收上面的回调
var p1 =p.then(function(res){
})。执行后返回一个promise对象,但和p不是同一个对象。当p1执行了并且return出res,就可以连缀
p1=p.then(function(res){
return res
}).then(function(data){
//处理成功回调
}).catch(function(){
//处理失败回调
})
可以简写p.then(function(res){
//处理成功信息
},function(err){
//处理异常信息
})。但一般不这样写。
使用案例如下,

promise的then方法是异步方法,但会优先于定时器执行。

JS中promise对象的作用与使用

promise的作用:ajax是异步请求,多层嵌套会造成回调地狱,promise模拟同步,将异步回调类似于同步来处理业务逻辑。
var p = new Promise(function(){
//这里用于处理异步的回调

}),必传回调函数,不传程序会抛出异常。
创建实例对象时,回调函数会立即执行。
promise的三种状态:
pending:正在进行状态
fulfilled:完成状态
rejected:失败状态
传参1 resolve,是个函数,只要这个函数执行了说明是成功状态,参数2选传,rejecte,是个函数,这个函数执行了说明是失败状态。这两个只能执行一个,变化不可逆。
promise两种结果:
从进行到失败
从进行到成功
通过rejecte(data)h或者resolve(data)将异步响应的数据提取出来,在promise外部使用。
promise的then方法,用于处理成功或者失败的回调。
//接收上面的回调
var p1 =p.then(function(res){
})。执行后返回一个promise对象,但和p不是同一个对象。当p1执行了并且return出res,就可以连缀
p1=p.then(function(res){
return res
}).then(function(data){
//处理成功回调
}).catch(function(){
//处理失败回调
})
可以简写p.then(function(res){
//处理成功信息
},function(err){
//处理异常信息
})。但一般不这样写。
使用案例如下,

promise的then方法是异步方法,但会优先于定时器执行。

Promise的用法以及作用

  Promise是一种常用的异步解决方案,解决回调地狱的问题。

  Promise可以解决两个问题:

  Promise发送的请求会经历三个过程:padding(进行中)、fullfilled(成功)、rejected(失败)。当状态决定后就不会在改变,这个时候就会把状态改为resolved(已定型)

  我通常配合vue和axios进行使用。

Promise有以下函数:

通常"Promise.resolve().then(f) "用这种方式把f变成符合promise的函数,但是如果f是同步函数这就会导致f只会在本段程序的末尾执行,有两种写法可以解决这个问题。

  方法一:第一种写法是用async函数来写。

  方法二:第二种写法是使用new Promise()。

p.try()就是解决以上的执行方式的痛点 Promise.try 为所有操作提供了统一的处理机制,所以如果想用 then 方法管理流程,最好都用 Promise.try 包装一下。这样有 许多好处 ,其中一点就是可以更好地管理异常。

javascript%20是什么意思?

1、在Javascript中,在语句执行中,%代表取模,俗称取余数,例如

10%10

return value: 0

10%20

return value: 10

2、在浏览器地址编码中,%可以代表一个编码的开始,例如

%20         代表的是空格

Javascript脚本语言同其他语言一样,有它自身的基本数据类型,表达式和算术运算符

及程序的基本程序框架。Javascript提供了四种基本的数据类型和两种特殊数据类型用来处理数据和

文字。而变量提供存放信息的地方,表达式则可以完成较复杂的信息处理。

扩展资料:

JavaScript脚本语言具特点:

1、脚本语言。JavaScript是一种解释型的脚本语言,C、C++等语言先编译后执行,而JavaScript是在程序的运行过程中逐行进行解释。

2、基于对象。JavaScript是一种基于对象的脚本语言,它不仅可以创建对象,也能使用现有的对象。

3、简单。JavaScript语言中采用的是弱类型的变量类型,对使用的数据类型未做出严格的要求,是基于Java基本语句和控制的脚本语言,其设计简单紧凑。

4、动态性。JavaScript是一种采用事件驱动的脚本语言,它不需要经过Web服务器就可以对用户的输入做出响应。在访问一个网页时,鼠标在网页中进行鼠标点击或上下移、窗口移动等操作JavaScript都可直接对这些事件给出相应的响应。

5、跨平台性。JavaScript脚本语言不依赖于操作系统,仅需要浏览器的支持。因此一个JavaScript脚本在编写后可以带到任意机器上使用,前提上机器上的浏览器支 持JavaScript脚本语言,目前JavaScript已被大多数的浏览器所支持。 

不同于服务器端脚本语言,例如PHP与ASP,JavaScript主要被作为客户端脚本语言在用户的浏览器上运行,不需要服务器的支持。所以在早期程序员比较青睐于JavaScript以减少对服务器的负担,而与此同时也带来另一个问题:安全性。

而随着服务器的强壮,虽然程序员更喜欢运行于服务端的脚本以保证安全,但JavaScript仍然以其跨平台、容易上手等优势大行其道。同时,有些特殊功能(如AJAX)必须依赖Javascript在客户端进行支持。随着引擎如V8和框架如Node.js的发展,及其事件驱动及异步IO等特性,JavaScript逐渐被用来编写服务器端程序。

参考资料来源:百度百科-javascript

站点网还为您提供以下相关内容希望对您有帮助:

这段es6 JavaScript代码应该怎么理解呢?关于promise的

首先,创建了一个名为 p1 的新 Promise,并立即将其解析为值 1。然后,在 p1 的 then 方法中,我们调用了一个名为 p2 的函数,该函数返回一个新的 Promise。然后,我们又在 p2 的 then 方法中调用了名为 p3 的函...

前端的Promise是干啥的?

promise的then方法带有以下三个参数:成功回调,失败回调,前进回调,一般情况下只需要实现第一个,后面是可选的。Promise中最为重要的是状态,通过then的状态传递可以实现回调函数链式操作的实现。先执行以下代...

JS的Promise兄弟

1、Promise.resolve()的作用将现有对象转为Promise对象resolved;Promise.resolve('test')==new Promise(resolve=>resolve('test'))2、Promise.reject()返回一个Promise对象,状态为rejected 3、Promise.prototype.then()方法接受...

promise.all和promise.race的区别

1、并行执行:Promise.all是一个JavaScriptPromise方法,接收一个Promise对象数组作为参数,并在全部Promise对象都成功解决(resolved)时返回一个新的Promise对象。Promise.all会执行全部的Promise对象,只有当全部Promise对象都成功...

以jQuery中$.Deferred对象为例讲解promise对象是如何处理异步问题_jquery...

一、封装异步操作首先,我们以加载图片为例,看以下代码:以上的代码,我封装了图片加载的操作,将他们委托给$.Deferred,最后生成一个promise返回。使用这样的方式,相比用对外暴露回调的方式,显得更干净、更清晰。这么做的另...

Promise简书

常见用法:异步操作和定时器放在一起,,如果定时器先触发,就认为超时,告知用户;例如我们要从远程的服务家在资源如果5000ms还没有加载过来我们就告知用户加载失败 2.Promise.race() 与 Promise.all 类似,但只等待第一...

js Promise 等待多个异步操作执行完再去做一些操作

执行效果:只是返回了 失败回调,这显然不是我们想要的效果 但是,我们写好的时候,使用 Promise.all()方法的时候,想起来,Promise.all()这个方法,只要这个方法的任意一个 promise有reject也就是失败状态的时候,promise ...

promise 风格编程书写格式详解

如果这个事实让你难以接受,那么思考一下我在 Twitter 上出的题:问:下面四个使用 promise 的语句之间的不同点在哪儿?doSomething().then(function () { return doSomethingElse();});doSomethin().then(functiuoin ...

【Flutter】利用Future封装出js中的Promise

下面我们尝试,利用 Future 封装出js中我们熟悉的 Promise 。https://es6.ruanyifeng.com/#docs/promise 使用示例 Promise.all , Promise.race , Promise.resolve , Promise.reject Promise.allSettled 方法接受一组 ...

js async和await的用法

await 同 async 一样,作为修饰符,但是它只能放在 async 内部使用。 它是 获取 Promise 中返回的内容, 即这个 Promise 函数中 resolve 或者 reject 的值。所以,async 用于申明一个 function 是异步的,而 await ...

本文如未解决您的问题请添加抖音号:51dongshi(抖音搜索懂视),直接咨询即可。

精彩推荐

更多阅读

Top