Javascript:Promise 完整指南

WBOY
发布: 2024-08-26 21:36:02
原创
207 人浏览过

Javascript: Promise Complete Guide

什么是承诺?

Promise 是异步编程的一种新解决方案。 ES6已将其纳入语言标准,统一其用法并原生提供Promise对象。

它的引入极大地改善了异步编程的困境,避免了回调地狱。它比回调函数和事件等传统解决方案更合理、更强大。

Promise,简单地说,是一个构造函数,它保存将来将完成的事件(通常是异步操作)的结果。从语法上来说,Promise 是一个可以从中检索异步操作消息的对象。 Promise 提供了统一的 API,允许以相同的方式处理各种异步操作。

我们为什么要使用 Promise?

  • 可以有效解决ES5中的回调地狱问题(避免回调函数深度嵌套)。

  • 遵循统一标准,语法简洁,可读性强,可维护性强。

  • Promise 对象提供了简单的 API,让管理异步任务更加方便灵活。

Promise 的状态

使用 Promise 时,我们可以将其分为三种状态:

  1. 待处理:待处理。这是初始状态,Promise 既没有被履行,也没有被拒绝。

  2. 已完成:已完成/已解决/成功。当执行resolve()时,Promise立即进入该状态,表示已经解决,任务成功完成。

  3. 拒绝:拒绝/失败。当执行reject()时,Promise立即进入该状态,表示已被拒绝,任务失败。

当执行new Promise()时,promise对象的状态被初始化为pending,这是它的初始状态。 new Promise()行括号内的内容是同步执行的。在括号内,您可以为异步任务定义一个函数,该函数有两个参数:resolve 和reject。例如:

// Create a new promise const promise = new Promise((resolve, reject) => { //promise's state is pending as soon as entering the function console.log('Synchronous Operations'); //Begin to execute asynchronous operations if (Success) { console.log('success'); // If successful, execute resolve() to switch the promise's state to Fulfilled resolve(Success); } else { // If failed, excecute reject() to pass the error and switch the state to Rejected reject(Failure); } }); console.log('LukeW'); //Execute promise's then():to manage success and failure situations promise.then( successValue => { // Process promise's fulfilled state console.log(successValue, 'successfully callback'); // The successMsg here is the Success in resolve(Success) }, errorMsg => { //Process promise's rejected state console.log(errorMsg, 'rejected'); // The errorMsg here is the Failure in reject(Failure) } );
登录后复制

Promise 的基本用法

创建一个新的 Promise 对象

Promise 构造函数以一个函数作为参数,该函数有两个参数:resolve 和reject。

const promise = new Promise((resolve, reject) => { // ... some code if (/* Success */){ resolve(value); } else { reject(error); } });
登录后复制

Promise.resolve

Promise.resolve(value) 的返回值也是一个 Promise 对象,可以与 .then 调用链接起来。代码如下:

Promise.resolve(11).then(function(value){ console.log(value); // print 11 });
登录后复制

在resolve(11)代码中,它将导致promise对象转换到resolved状态,将参数11传递给后续.then中指定的onFulfilled函数。可以使用新的 Promise 语法或使用 Promise.resolve(value) 创建 Promise 对象。

承诺.拒绝

function testPromise(ready) { return new Promise(function(resolve,reject){ if(ready) { resolve("hello world"); }else { reject("No thanks"); } }); }; testPromise(true).then(function(msg){ console.log(msg); },function(error){ console.log(error); });
登录后复制

上面代码的意思是向testPromise方法传递一个参数,该方法返回一个promise对象。如果参数为true,则调用promise对象的resolve()方法,然后将传递给它的参数传递给后续.then中的第一个函数,结果是输出“hello world”。如果参数为 false,则调用 Promise 对象的reject() 方法,这会触发 .then 中的第二个函数,导致输出“NoThanks。”

Promise 中的方法

然后()

then 方法可以接受两个回调函数作为参数。第一个回调函数在Promise对象的状态变为resolved时调用,第二个回调函数在Promise对象的状态变为rejected时调用。第二个参数是可选的,可以省略。

then 方法返回一个新的 Promise 实例(不是原始的 Promise 实例)。因此,可以使用链式语法,在第一个方法之后调用另一个 then 方法。

当需要顺序编写异步事件,要求串行执行时,可以这样写:

let promise = new Promise((resolve,reject)=>{ ajax('first').success(function(res){ resolve(res); }) }) promise.then(res=>{ return new Promise((resovle,reject)=>{ ajax('second').success(function(res){ resolve(res) }) }) }).then(res=>{ return new Promise((resovle,reject)=>{ ajax('second').success(function(res){ resolve(res) }) }) }).then(res=>{ })
登录后复制
抓住()

除了then方法之外,Promise对象还有一个catch方法。该方法相当于then方法的第二个参数,指向reject的回调函数。不过catch方法还有一个额外的功能:如果在执行resolve回调函数时发生错误或者抛出异常,它不会停止执行。而是会进入catch方法。

p.then((data) => { console.log('resolved',data); },(err) => { console.log('rejected',err); } ); p.then((data) => { console.log('resolved',data); }).catch((err) => { console.log('rejected',err); });
登录后复制
all()

The all method can be used to complete parallel tasks. It takes an array as an argument, where each item in the array is a Promise object. When all the Promises in the array have reached the resolved state, the state of the all method will also become resolved. However, if even one of the Promises changes to rejected, the state of the all method will become rejected.

let promise1 = new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(1); },2000) }); let promise2 = new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(2); },1000) }); let promise3 = new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(3); },3000) }); Promise.all([promise1,promise2,promise3]).then(res=>{ console.log(res); //result:[1,2,3] })
登录后复制

When the all method is called and successfully resolves, the result passed to the callback function is also an array. This array stores the values from each Promise object when their respective resolve functions were executed, in the order they were passed to the all method.

race()

The race method, like all, accepts an array where each item is a Promise. However, unlike all, when the first Promise in the array completes, race immediately returns the value of that Promise. If the first Promise's state becomes resolved, the race method's state will also become resolved; conversely, if the first Promise becomes rejected, the race method's state will become rejected.

let promise1 = new Promise((resolve,reject)=>{ setTimeout(()=>{ reject(1); },2000) }); let promise2 = new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(2); },1000) }); let promise3 = new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(3); },3000) }); Promise.race([promise1,promise2,promise3]).then(res=>{ console.log(res); //result:2 },rej=>{ console.log(rej)}; )
登录后复制

So, what is the practical use of the race method? When you want to do something, but if it takes too long, you want to stop it; this method can be used to solve that problem:

Promise.race([promise1,timeOutPromise(5000)]).then(res=>{})
登录后复制
finally()

The finally method is used to specify an operation that will be executed regardless of the final state of the Promise object. This method was introduced in the ES2018 standard.

promise .then(result => {···}) .catch(error => {···}) .finally(() => {···});
登录后复制

In the code above, regardless of the final state of the promise, after the then or catch callbacks have been executed, the callback function specified by the finally method will be executed.

What exactly does Promise solve?

In work, you often encounter a requirement like this: for example, after sending an A request using AJAX, you need to pass the obtained data to a B request if the first request is successful; you would need to write the code as follows:

let fs = require('fs') fs.readFile('./a.txt','utf8',function(err,data){ fs.readFile(data,'utf8',function(err,data){ fs.readFile(data,'utf8',function(err,data){ console.log(data) }) }) })
登录后复制

The above code has the following drawbacks:

  • The latter request depends on the success of the previous request, where the data needs to be passed down, leading to multiple nested AJAX requests, making the code less intuitive.

  • Even if the two requests don't need to pass parameters between them, the latter request still needs to wait for the success of the former before executing the next step. In this case, you also need to write the code as shown above, which makes the code less intuitive.

After the introduction of Promises, the code becomes like this:

let fs = require('fs') function read(url){ return new Promise((resolve,reject)=>{ fs.readFile(url,'utf8',function(error,data){ error && reject(error) resolve(data) }) }) } read('./a.txt').then(data=>{ return read(data) }).then(data=>{ return read(data) }).then(data=>{ console.log(data) })
登录后复制

This way, the code becomes much more concise, solving the problem of callback hell.

以上是Javascript:Promise 完整指南的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!