このチュートリアルの動作環境: Windows 7 システム、ECMAScriptバージョン 6、Dell G3 コンピューター。3 つの状態があります: 1. 保留中 (処理中であることを意味し、この状態は初期化されます)、2. 完了 (成功したことを意味します)、3. 拒否 (失敗したことを意味します)後続の catch コールバック関数をトリガーします。プロミスのステータスは一度変更されると固定され、再度変更されることはなく、その結果は常に維持されます。
非同期プログラミング のためのソリューションであり、従来のソリューション (コールバック関数やイベント) よりも合理的で合理的です。より強力な。
いわゆる Promise は、将来終了するイベント (通常は非同期操作) の結果を保存する単なるコンテナーです。 構文的に言えば、Promise は非同期操作のメッセージを取得できるコンストラクターです。 Promise は統一された API を提供しており、さまざまな非同期操作を同じように処理できます。 Promise オブジェクトを使用すると、入れ子になったコールバック関数の層を回避して、非同期操作を同期操作プロセスとして表現できます。 Promise オブジェクトは統一されたインターフェイスを提供し、非同期操作の制御を容易にします。es5 はシングルスレッド言語であり、ステートメントの実行順序は上から下であることがわかっています。プロジェクトのフロントエンドがバックエンドに接続されている場合、ajax はajax は非同期であるため、データのやり取りが発生する可能性があり、遅延が発生し、プログラミングに役立ちません。 Promise 関数はこの問題をうまく解決できます。
Promiseコンストラクターは関数をパラメーターとして受け取り、関数の 2 つのパラメーターは
です。解決と
拒否。これら 2 つのパラメーターは、JavaScript エンジンによって提供される 2 つの関数です。
保留中 (進行中) 、履行 (成功) 、および 拒否 (失敗)# # の 3 つの状態があります。 #。
と呼ばれます。 ステータス変更:
1.保留中 ->解決済み
2.保留中 ->拒否
状態の発現
#拒否されました状態は後続のキャッチ コールバック関数をトリガーします
const promise = new Promise(function(resolve,reject){ //...some code if(/*异步操作成功*/){ resolve(value); // 状态由pending变为fulfilled }else{ reject(error); // 状态由pending变为rejected } })
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>测试</title> </head> <body> <script> let promise = new Promise(function (resolve, reject) { if (3 < 5) { resolve("是正确的"); } else { reject("是错误的"); } }) console.log(promise); </script> </body> </html>
結果:
Promise のプロトタイプ メソッド
Promise.prototypeこのコールバック関数は、ステータスが保留中から完了に変わったときに実行されます。パラメータ:
戻り値:
新しい Promise インスタンス オブジェクトを返すため、 チェーン コールを使用できます
。 Promise が履行されるか拒否されると、return 関数が非同期的に呼び出されます (現在のスレッド ループによってスケジュールされます)。具体的な戻り値は以下の規則に従って返却されます。 then:のコールバック関数が値を返す場合、then によって返された Promise は受け入れ状態となり、返された値はコールバック関数のパラメーター値として使用されます。それは状態を受け入れることです。
値が返されない場合、それまでに返された Promise が受理状態となり、受理状態のコールバック関数のパラメータ値は不定となります。
返回一个已经是接受状态的 Promise,那么 then 返回的 Promise 也会成为接受状态,并且将那个 Promise 的接受状态的回调函数的参数值作为该被返回的Promise的接受状态回调函数的参数值。
返回一个已经是拒绝状态的 Promise,那么 then 返回的 Promise 也会成为拒绝状态,并且将那个 Promise 的拒绝状态的回调函数的参数值作为该被返回的Promise的拒绝状态回调函数的参数值。
返回一个未定状态(pending)的 Promise,那么 then 返回 Promise 的状态也是未定的,并且它的终态与那个 Promise 的终态相同;同时,它变为终态时调用的回调函数参数与那个 Promise 变为终态时的回调函数的参数是相同的。
将上面的规则简单总结:
1、如果回调函数中的返回结果是promise对象,则对象状态由回调函数的执行结果决定
2、如果回到函数中的返回结果为非promise对象(无论是字符串、undefined…只要不是promise对象),对象状态均为成功,返回值为对象成功调用中的值。
3、throw抛出错误,状态为rejected
let p1 = new Promise((resolve, reject) => { resolve('成功!'); // 或者 // reject(new Error("出错了!")); }); p1.then(value => { console.log(value); // 成功! }, error => { console.log(error); // 出错了! });
当状态由pending变为rejected的时候执行该回调函数,
参数:
回调函数,回调函数的参数为reject函数传递过来的值
返回值:
返回一个新的Promise实例对象,因此可以使用链式调用。
// 抛出一个错误,大多数时候将调用catch方法 let p1 = new Promise(function(resolve, reject) { throw 'Uh-oh!'; }); p1.catch(function(e) { console.log(e); // "Uh-oh!" });
推荐使用catch方法,不要在then方法中定义rejected状态的回调函数;这是因为使用catch还可以捕获在then方法执行中存在的错误。
// bad promise.then(function(data) { // success }, function(err) { // error }); // good promise.then(function(data) { // success }) .catch(function(err) { // error })
finally() 方法返回一个Promise。在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数。这为在Promise是否成功完成后都需要执行的代码提供了一种方式。这避免了同样的语句需要在then()和catch()中各写一次的情况。
参数:
回调函数,不接收任何参数
返回值:
返回一个新的Promise实例对象
let p1 = new Promise(function(resolve, reject) { throw 'Uh-oh!'; }); p1.catch(function(e) { console.log(e); // "Uh-oh!" }).finally(function() { console.log('这段代码最终都会执行'); });
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <title>promise基本使用</title> </head> <body> <script> let promise = new Promise(function(resolve,reject){ // ajax发送异步请求 $.ajax({ // 请求路径 url:'http://47.100.84.201:8888/carousel/findAll', // 成功回调 success(res){ console.log("成功回调",res); // 通过resolve将成功的回调传递出去 //resolve(res); }, // 失败回调 error(err){ console.log("失败回调",err); // 通过reject将失败的回调传递出去 //reject(err); } }) }) // 通过promise实例对象的实例方法对数据进行操作 promise .then(res => console.log("接收到resolve传递过来的数据" + res)) .catch(err => console.log("接收reject传递的数据" + err)) .finally(()=>{ console.log("无论成功还是失败都会调用!") }) </script> </body> </html>
分析:当在promise实例对象中ajax的两个回调函数中使用
console.log("成功回调",res)
和console.log("失败回调",err);
语句反映调用结果(成功或失败)时,浏览器控制台并不会执行then\catch\finally方法中的内容,因为此时then方法中并没有接收到来自ajax的res,catch方法有没有接收到来自ajax的err,所以并不会执行箭头函数中的语句。
当改为resolve(res);
和reject(err);
时结果如下:
const fs = require("fs"); fs.readFile('../FILE/first.txt',(err,data1) => { fs.readFile('../FILE/second.txt',(err,data2)=>{ fs.readFile('../FILE/second.txt',(err,data3)=>{ let result = data1 + '\t\n' + data2 + '\t\n' + data3; console.log(result); //... //如果后面还有其他文件呢,会导致回调地狱,代码会横向变得很宽很长,并且这里data不能重名,需要不断的取名字 }); }); });
第二种方式:
使用promise实现,解决缩进问题
const fs = require("fs"); // 初始化promise:读取第一个文件,使用resolve函数传递出去读取到的数据,用Promise对象接收 const promise = new Promise((resolve,reject)=>{ fs.readFile('../FILE/first.txt',(err,data)=>{ resolve(data); }) }) // 执行回调函数 promise.then(value => { //先看能不能获取到value值 // console.log(value); //输出的是buffer // console.log(value.toString()); //可以使用toString方法转化buffer为正常字符串 // then方法的返回值是一个promise对象,所以这里直接使用return返回一个promise对象 return new Promise((resolve,reject)=>{ // promise中的主要操作也是读取文件内容 fs.readFile('../FILE/second.txt',(err,data)=>{ // 将读取到的数据传递出去,这里将读取到的数据放到了数组中,一起传了出去 // value是初始化时读取文件first.txt的内容,data指的是当前读到的文件内容 resolve([value,data]); }) }) //使用链式调用方式继续调用,读取下一个文件的内容 }).then(value=>{ return new Promise((resolve,reject)=>{ fs.readFile('../FILE/third.txt',(err,data)=>{ // 将读取到的data通过push方法添加进数组中 // 这里的value是前面传过来的数组 value.push(data); resolve(value); }) }) }).then(value=>{ // 输出一一读取文件后的结果 console.log(value.toString()); // 这是第一个文件,这是第二个文件,这是第三个文件 // 文件间通过逗号分隔 })
虽然目前使用promise的代码量确实比较多,但却可以避免代码横向增多的问题,不会影响代码阅读
定义在Promise中的方法,通过Promise可以直接调用。
Promise.all用于将多个 Promise 实例,包装成一个新的 Promise 实例
参数:
数组,数组中的元素为Promise实例
返回值:
Promise实例,当p1,p2状态都为fulfilled时候,该实例的状态才为fulfilled,此时p1,p2的返回值组成一个数组,传递给该实例的回调函数;只要p1,p2的返回值有一个变为rejected,该实例状态为rejected。
const promise1 = Promise.resolve(3); //该方法用于将现有对象转化为Promise实例 const promise2 = 42; const promise3 = new Promise((resolve, reject) => { setTimeout(resolve, 100, 'foo'); }); Promise.all([promise1, promise2, promise3]).then((values) => { console.log(values); }); // expected output: Array [3, 42, "foo"]
Promise.race用于将多个 Promise 实例,包装成一个新的 Promise 实例
参数:
数组,数组中的元素为Promise实例
返回值:
Promise实例,当p1,p2之中有一个实例率先改变状态,该实例的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给该实例的回调函数。(谁执行的快就返回谁)
const promise1 = new Promise((resolve, reject) => { setTimeout(resolve, 500, 'one'); }); const promise2 = new Promise((resolve, reject) => { setTimeout(resolve, 100, 'two'); }); Promise.race([promise1, promise2]).then((value) => { console.log(value); // Both resolve, but promise2 is faster }); // expected output: "two"
用于将多个 Promise 实例,包装成一个新的 Promise 实例
参数:
数组,数组中的元素为Promise实例
返回值:
Promise实例,只要p1,p2状态有一个变为fulfilled,该实例的状态为fulfilled;p1,p2状态都变为rejected,该实例状态才为rejected。
const pErr = new Promise((resolve, reject) => { reject("总是失败"); }); const pSlow = new Promise((resolve, reject) => { setTimeout(resolve, 500, "最终完成"); }); const pFast = new Promise((resolve, reject) => { setTimeout(resolve, 100, "很快完成"); }); Promise.any([pErr, pSlow, pFast]).then((value) => { console.log(value); // pFast fulfils first }) // expected output: "很快完成"
用于将现有对象转化为Promise实例
参数:
任意值
const promise1 = Promise.resolve(123); promise1.then((value) => { console.log(value); // expected output: 123 });
返回一个新的 Promise 实例,该实例的状态为rejected。
参数:
错误信息
Promise.reject(new Error('fail')).then(function() { // not called }, function(error) { console.log(error); // Stacktrace });
【相关推荐:javascript视频教程、web前端】
以上がes6 Promiseにはいくつかの状態がありますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。