ホームページ  >  記事  >  ウェブフロントエンド  >  Promise を始めるために知っておくべきこと

Promise を始めるために知っておくべきこと

php中世界最好的语言
php中世界最好的语言オリジナル
2018-03-19 14:27:071359ブラウズ

今回はPromiseを始める際に知っておくべき注意事項についてお届けします。

Promise は非同期プログラミングのソリューションです。構文的に言えば、Promise は非同期操作のメッセージを取得できるオブジェクトです。

Promiseの基本的な使い方

PromiseConstructorは関数をパラメータとして受け取り、関数の2つのパラメータはresolveとrejectです。これらは JavaScript エンジンによって提供される 2 つの関数です。

  • resolve 関数の役割は、Promise オブジェクトの状態を「未完了」から「成功」(つまり、保留中から解決済み) に変更することであり、非同期操作が成功したときに呼び出され、その結果を使用します。パラメータが渡されるときの非同期操作の。

  • reject 関数の機能は、Promise オブジェクトのステータスを「未完了」から「失敗」(つまり、保留中から拒否済み) に変更することです。

    は、非同期操作が失敗したときに呼び出され、非同期操作を報告します。操作エラーはパラメータとして渡されます。

  • then メソッドは、パラメータとして 2 つの
  • コールバック関数

    を受け入れることができます。 最初のコールバック関数は、Promise オブジェクトの状態が Resolved に変化したときに呼び出され、2 番目のコールバック関数は、Promise オブジェクトの状態が Reject に変化したときに呼び出されます

    var promise = new Promise(    //异步执行,Promise对象创建后会被立即执行
        function (resolve,reject) {        //耗时很长的异步操作  if('异步处理成功') {  
            resolve();    //数据处理成功时调用  } else {
            reject();    //数据处理失败时调用    }
            
        }
    )//Promise实例生成以后,可以用then方法分别指定Resolved状态和Reject状态的回调函数。promise.then(    function A() {        //数据处理成功后执行    },    function B() {        //数据处理失败后执行    }
    )
  • 非同期操作の成功関数と非同期操作失敗関数の実行プロセスをシミュレートする簡単な例を見てみましょう。
console.log('starting' promise =  Promise("2秒后,我运行了"'异步操作成功了');     
        
    }, 2000'异步操作成功后执行我:''异步操作失败后执行我:''我也运行了'
知代码3处的return 'hello' 语句在新建的new Promise对象中并没有被当作参数返回给then()函数内.那么会不会返回给promise了呢?我们用一段代码来测试一下
console.log('starting');var promise = new Promise(function(resolve, reject) {  
    setTimeout(function() { 
        console.log("2秒后,我运行了");
        resolve('异步操作成功了');     //1
        //reject('异步操作失败了');    //2
        return 'hello';
    }, 2000) 
    
})
promise.then(function (value) { 
    console.log('异步操作成功后执行我:',value);
},function (value) {
    console.log('异步操作失败后执行我:',value);
}
)
console.log('我也运行了');
console.log(promise);
setTimeout(function () {
    console.log('5秒后,我执行了');
    console.log(promise);
},5000);//starting//我也运行了//Promise { pending }  //[[PromiseStatus]]:"pending"  //[[PromiseValue]]:undefined  //proto:Promise {constructor: , then: , catch: , …}//2秒后,我运行了//异步操作成功后执行我: 异步操作成功了//5秒后,我执行了//Promise { resolved }  //[[PromiseStatus]]:"resolved"  //[[PromiseValue]]:"异步操作成功了"  //proto:Promise {constructor: , then: , catch: , …}

実行結果から、変数 Promise はまだ新しい Promise オブジェクトのインスタンスであることがわかります。したがって、return ステートメントは実行されますが、Promise インスタンスには何の影響も与えず、存在しないことと同じになります。

上記でテストしたコードからわかるように、Promise オブジェクトには次の 2 つの特徴があります。

(1) 物体の状態は外界の影響を受けない。 Promise オブジェクトは非同期操作を表し、保留中 (進行中)、解決済み (完了、フルフィルドとも呼ばれる)、拒否済み (失敗) の 3 つの状態があります。

現在の状態がどの状態であるかを決定できるのは非同期操作の結果だけです
(2)一度状態が変化すると再度変化することはなく、いつでも結果を得ることができます。 Promise オブジェクトの状態が変化する可能性は 2 つだけです。保留中から解決済みへ、および保留中から拒否へです。この 2 つの状況が発生する限り、状態は固定され、再び変化することはなく、この結果が維持されます。すでに変更が行われている場合でも、Promise オブジェクトにコールバック関数を追加すると、すぐに結果が得られます。イベントとは全く違いますが、聞き逃してまた聞き直すと結果が出ないのがイベントの特徴です。

resolve(value) VSsolve(Promise)

非同期操作が成功したときに、resolve 関数

を呼び出します。その機能は、

Promise オブジェクトの状態を Pending から Resolved に変更し、その結果を渡すことです。パラメータとしての非同期操作 then() メソッドの最初の関数に仮パラメータ を与えます。 それでは、渡されたパラメータが値である場合と、渡されたパラメータが Promise オブジェクトである場合の違いは何でしょうか。例を見てみましょう。

渡されたパラメータが値の場合:

var time = new Date();var promise = new Promise(function(resolve, reject) {  
    setTimeout(function() { 
        console.log("1秒后,我运行了");
        resolve('异步操作成功了');     //1
    }, 2000) 
    
}).then(function (value) {
    console.log(value,new Date() - time);
})//执行的输出结果为://2秒后,我运行了//异步操作成功了 1002
約 1 秒ほど後、解決された状態のコールバック メソッドで、上記のコメントの内容が出力されていることがわかります。操作の結果をsolve メソッドを通じて渡し、その結果をコールバック メソッドで使用できます。

解決で Promise インスタンスを渡したらどうなるでしょうか?

 time =  promise =  Promise("2秒后,我运行了"'异步操作成功了');     2000 promise2 =  Promise(1000 Date() -
promise2 は 2 秒後に結果を出力します。奇妙なことに、promise2 は 1 秒後に実行されるように設定していませんでしたか?

簡単に言うと、promise2のresolve()関数がpromiseオブジェクトを渡すため、このときpromiseオブジェクトの状態がpromiseの状態を決定し、戻り値がpromiseに渡されるからです。

Promise/A+ は

[[Resolve]](promise, x)2.3.2 を規定します。x が Promise インスタンスの場合、x の状態は Promise の状態として使用されます

2.3.2.1。の約束も、x の状態が変わるまで保留中です。

2.3.2.2. x のステータスが満たされると、promise のステータスも満たされ、x の不変値が promise の不変値として使用されます。

  2.3.2.3.如果x的状态为rejected, promise的状态也为rejected, 并且以x的不可变原因作为promise的不可变原因。

2.3.4.如果x不是对象或函数,则将promise状态转换为fulfilled并且以x作为promise的不可变值。

 Promise.prototype.then()

Promise实例具有then方法,也就是说,then方法是定义在原型对象Promise.prototype上的。它的作用是为Promise实例添加状态改变时的回调函数。 前面说过,then方法的第一个参数是Resolved状态的回调函数,第二个参数(可选)是Rejected状态的回调函数。

then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。

var promise = new Promise(function(resolve, reject) {  
    setTimeout(function() { 
        console.log("2秒后,我运行了");
        resolve('异步操作成功了');     //1
    }, 2000) 
    
})
promise.name = 'promise';
console.log('promise:',promise)var promise2 = promise.then(function (value) {
    console.log(value);
})
promise2.name = 'promise2';
console.log('promise2:',promise2);// promise://     Promise { pending }//     [[PromiseStatus]]:"pending"//     [[PromiseValue]]:undefined//     name:"promise"//     proto:Promise {constructor: , then: , catch: , …}// promise2:// Promise { pending }//     [[PromiseStatus]]:"pending"//     [[PromiseValue]]:undefined//     name:"promise2"//     proto:Promise {constructor: , then: , catch: , …}

我们可以知道promise.then()方法执行后返回的是一个新的Promise对象。也就是说上面代码中的promise2是一个Promise对象,它的实现效果和下面的代码是一样的,只不过在then()方法里,JS引擎已经自动帮我们做了。

promise2 = new Promise(function (resolve,reject) {})

既然在then()函数里已经自动帮我实现了一个promise对象,但是我要怎么才能给resolve()或reject()函数传参呢?其实在then()函数里,我们可以用return()的方式来给promise2的resolve()或reject()传参。看一个例子。

 promise =  Promise("2秒后,我运行了"'异步操作成功了');     
        
    }, 2000 promise2 = promise.then(
     (1 promise3 = promise2.then('is:''error:'= 'promise2'3000

Promise与错误状态处理

.then(null, rejection),用于指定异步操作发生错误时执行的回调函数。下面我们做一个示例。

var promise = new Promise(function(resolve, reject) {
    setTimeout(function () {
            reject('error');
    },2000);
}).then(null,function(error) {
    console.log('rejected', error)
});//rejected error

我们知道then()方法执行后返回的也是一个promise对象,因此也可以调用then()方法,但这样的话为了捕获异常信息,我们就需要为每一个then()方法绑定一个.then(null, rejection)。由于Promise对象的错误信息具有“冒泡”性质,错误会一直向后传递,直到被捕获为止。因此Promise为我们提供了一个原型上的函数Promise.prototype.catch()来让我们更方便的 捕获到异常。

我们看一个例子

var promise = new Promise(function(resolve, reject) {
    setTimeout(function () {
            reject('error');
    },2000);
}).then(function(value) {
    console.log('resolve', value);
}).catch(function (error) {
    console.log(error);
})//运行结果//error

上面代码中,一共有二个Promise对象:一个由promise产生,一个由then产生。它们之中任何一个抛出的错误,都会被最后一个catch捕获。

但是如果用.then(null, rejection)方法来处理错误信息,我们需要在每一个rejection()方法中返回上一次异常信息的状态,这样当调用的then()方法一多的时候,对会对代码的清晰性和逻辑性造成影响。

所以,一般来说,不要在then方法里面定义Reject状态的回调函数(即then的第二个参数),总是使用catch方法。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

在前端中的html基础知识 

知名的网站前端布局分析
关于前端的css基本知识

以上がPromise を始めるために知っておくべきことの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。