// プロミス実装原理 // 方法例 // 次に // キャッチ // 新しい新しいP(関数).then(functon(){})を(関数(){}) // 新しい新しいMyPromise P =()とします。 // p.resolve(); //許可 // 静的メソッド // すべて // レース // 特性 // ステータス:保留/分解/拒否 // 解決/拒否 // 、各オブジェクトを約束しており、ステータス最初に状態をペンディング // このプロパティは、直接のみコールバックを変更することによって変更されない // 状態を不可逆的に修飾された後、および。 @ 目的関数が実行されると、必要な送信パラメータは、解決拒否である 関数{(メイン)MyPromiseを ステータスLET =「保留」; // 初期化状態単に作成MyPromise LET = listTaskは[]を; // で.then()関数を格納するための配列、定義 LET exceptionHander = ヌル ; // エラーキャプチャする 機能決意を(MSG){ // 関数解決()メソッドが呼び出された返した場合 IF(ステータス==「保留」){ // ステータスがペンディングされている場合の実行、又は実行されず、プログラムが終了 =「解決」状態を、 // 関数を円滑実行状態の後解決約束 させ次にlistTask.shift =(); // うちの第1のアレイ のlet NEWP = 次に(MSG)を、 IF(NEWP のinstanceofの MyPromise){// 関数が新しいMyPromise外にもある場合、実行される listTask.forEach(T => { newp.then(T); // 例新しいMyPromise(ajaxB).then(関数 (){)}(ajaxC)新しいMyPromiseを返します.then(ajaxD).catch(関数(E)はconsole.log {(E)}) }) } } } 関数拒否(MSG){ // 戻り、この機能を実行するために、拒否した場合 IF(ステータス== "保留") { // 現在の状態がMyPromise保留されている場合 、ステータスは=「拒否」; // 変更ステータスは例外がスローされ、拒否され、MSGで出力方法 IF(exceptionHander){ // 呼び出し、そうでない場合、エラーがキャッチ } さもなければ{ exceptionHander(MSG); } } } この .then = 機能(タスク){ // すべて.then添加listTask新しいアレイの背後に講義プロミス にconsole.log(この); listTask.push(タスク); 戻り 、この ; // 戻り、循環を加え }、 この。キャッチ = 関数(FN){ exceptionHander = のFn; } この .getStatus = 関数(){ リターンステータス; } メイン(解決、rejected.bind(本)); // 最初の二つの基準関数には、二つの機能はまた、それ以外の場合はエラー、パラメータが受信された設定 } MyPromise.all = 関数(引数){ LETのCOUNT = 0 ; LETタスク = NULL ; 機能ISOVERである(){ COUNT ++ ; IF(COUNT == args.length)タスク(); } args.forEach(P => { p.then(ISOVERである); }) 戻り、次いで(FN)を{ タスク = のFn; } }
上記のテスト
<スクリプトSRC = "Promise.js"> </ SCRIPT> <! - <スクリプトSRC = "原生JS实现Promise.js"> </ SCRIPT> - > <スクリプト> 機能ajaxA(拒否、解決){ コンソール.logの( "スタートajaxA!" ); setTimeout(() => { はconsole.logは( "ajaxAが終了!" ); 解決(); }、Math.random() * 2000年) } 関数ajaxB(解決、拒否){ はconsole.log( "ajaxBスタート!" ); setTimeout(() => ); 決意(); }、Math.random() * 2000年) } 機能ajaxC(拒否、解決){ はconsole.log( "ajaxCがスタート!" ); setTimeout(() => { にconsole.log( "ajaxCを終了!" ); 拒否( "III" ); }、Math.random() * 2000 ) } 新しい MyPromise(ajaxA).then(関数(){ 戻り 新しいですMyPromise(ajaxB); 。})を(ajaxC)。キャッチ(関数(E){ にconsole.log(E); }) </ SCRIPT>
//プロミス実装の原則
//インスタンスメソッド
//その後、
//キャッチ
//新しいP(函数).then(functon(){})。次に、(関数(){})
//)pは=新しいMyPromise(みましょう。
// p.resolveは(); //許されません
//静的メソッド
// すべて
//レース
//プロパティ
//ステータス:保留/拒否/解決
//決意/拒否
各オブジェクトを約束前記//、ステータスが保留初期状態であります
//プロパティは、コールバックによって変更することができ、直接変更することはできません
//そして、状態が変更されると、不可逆的に。
目的関数は、あなたがパラメータを渡す必要がある場合、解決に実行//、拒否
関数
MyPromise
(
メイン
){
LETの
ステータス
=
「
保留
」
;
// MyPromiseだけの初期化状態を作成します
せ
listTaskは
=
[]
;
//は、アレイ、.then記憶するための()関数を定義します
let exceptionHander
=
null
;
//用于捕捉错误
function
resolve
(
msg
){
//如果函数返回resolve()方法则调用
if(status
==
"
pending
")
{
//如果状态为pending则执行,否则不执行,程序结束
status
=
"
resolve
"
;
//函数顺利执行完将promise状态改为resolve
let next
= listTask
.
shift()
;
//拿出数组中第一个
let newp
=
next(msg)
;
if(newp
instanceof
MyPromise)
{
//如果拿出来函数也new MyPromise,则执行
listTask
.
forEach(
t
=>
{
newp
.
then(t)
;
//例 new MyPromise(ajaxB).then(function(){ return new MyPromise(ajaxC)}).then(ajaxD).catch(function(e){console.log(e)})
})
}
}
}
function
rejected
(
msg
){
//如果返回rejected,执行此函数
if(status
==
"
pending
")
{
//如果当前MyPromise状态为pending
status
=
"
rejected
"
;
//更改状态为rejected ,抛出异常,输出方法里的msg
if(exceptionHander)
{
//有catch则调用,否则报错
}
else
{
exceptionHander(msg)
;
}
}
}
this
.
then
=
function
(
task
){
//讲第一个new Promise后面所有.then加入listTask数组里
console
.
log(
this)
;
listTask
.
push(task)
;
return
this
;
//返回,循环加入
},
this
.
catch
=
function
(
fn
){
exceptionHander
= fn
;
}
this
.
getStatus
=
function
(){
return status
;
}
main(resolve
,rejected
.
bind(
this))
;
//给第一个函数两个参,函数也需要设置两个参数接收,否则报错
}
MyPromise
.
all
=
function
(
args
){
let count
=
0
;
let task
=
null
;
function
isOver
(){
count
++
;
if(count
== args
.length)
task()
;
}
args
.
forEach(
p
=>
{
p
.
then(isOver)
;
})
return
then(fn)
{
task
= fn
;
}
}