ホームページ  >  記事  >  ウェブフロントエンド  >  PromiseA+の導入手順を詳しく解説

PromiseA+の導入手順を詳しく解説

php中世界最好的语言
php中世界最好的语言オリジナル
2018-05-24 13:39:172178ブラウズ

今回はPromiseA+の導入手順について詳しく解説していきます。PromiseA+導入時の注意点について、実際の事例を見てみましょう。

Promise

PromiseA+ の実装を手書きで作成しました。これは単なるシミュレーションであることに注意してください。実際、ネイティブ Promise はイベント キュー内の microTask に属します。ここでのシミュレーションに setTimeout を使用することは特に適切ではありません。 setTimeout はマクロタスクであるためです。

1. 最も単純な基本関数

/**
 * 定义Promise
 * 先实现一个最简单的。用setTimeout模拟一个异步的请求。
 */
function Promise(fn){
  var value= null;
  var callbacks = [];
  this.then = function(onFulfilled) {
    callbacks.push(onFulfilled);
  }
  function resolve(value){
    callbacks.forEach(function(cb){
      cb(value);
    })
  }
  fn(resolve);
}
// 使用Promise
var p = new Promise(function(resolve){
  setTimeout(function(){
    resolve('这是响应的数据')
  },2000)
})
p.then(function(response){
  console.log(response);
})

2. 非同期

/**
 * 先看一下前一个例子存在的问题
 * 1.在前一个例子中不断调用then需要支持链式调用,每次执行then都要返回调用对象本身。
 * 2.在前一个例子中,当链式调用的时候,每次then中的值都是同一个值,这是有问题的。其实第一次then中的返回值,应该是第二次调用then中的函数的参数,依次类推。
 * 所以,我们进一步优化一下代码。
 * 
 */
function Promise(fn){
  var value= null;
  var callbacks = [];
  this.then = function(onFulfilled) {
    callbacks.push({f:onFulfilled});
    return this;
  }
  function resolve(value){
    callbacks.map(function(cb,index){
      if(index === 0){
        callbacks[index].value = value;
      }
      var rsp = cb.f(cb.value);
      if(typeof callbacks[index+1] !== 'undefined'){
        callbacks[index+1].value = rsp;
      }
    })
  }
  fn(resolve);
}
// 使用Promise
var p = new Promise(function(resolve){
  setTimeout(function(){
    resolve('这是响应的数据')
  },2000)
})
p.then(function(response){
  console.log(response);
  return 1;
}).then(function(response){
  console.log(response);
  return 2;  
}).then(function(response){
  console.log(response);
})

4. 登録された関数の戻り値がpromiseの場合の処理​​

/**
 * 先看一下前一个例子存在的问题
 * 1. 如果在then方法注册回调之前,resolve函数就执行了,怎么办?比如 new Promise的时候传入的函数是同步函数的话,
 * then还没被注册,resolve就执行了。。这在PromiseA+规范中是不允许的,规范明确要求回调需要通过异步的方式执行。
 * 用来保证一致可靠的执行顺序。
 * 
 * 因此我们需要加入一些处理。把resolve里的代码放到异步队列中去。这里我们利用setTimeout来实现。
 * 原理就是通过setTimeout机制,将resolve中执行回调的逻辑放置到JS任务队列末尾,以保证在resolve执行时,
 * then方法的回调函数已经注册完成
 * 
 */
function Promise(fn){
  var value= null;
  var callbacks = [];
  this.then = function(onFulfilled) {
    callbacks.push({f:onFulfilled});
    return this;
  }
  function resolve(value){
    setTimeout(function(){
        callbacks.map(function(cb,index){
          if(index === 0){
            callbacks[index].value = value;
          }
          var rsp = cb.f(cb.value);
          if(typeof callbacks[index+1] !== 'undefined'){
            callbacks[index+1].value = rsp;
          }
        })
    },0)
  }
  fn(resolve);
}
// 使用Promise,现在即使是同步的立马resolve,也能正常运行了。
var p = new Promise(function(resolve){
    resolve('这是响应的数据')
})
p.then(function(response){
  console.log(response);
  return 1;
}).then(function(response){
  console.log(response);
  return 2;  
}).then(function(response){
  console.log(response);
})

この記事の事例を読んだ後は、その方法を習得したことになります。さらに興味深い情報については、PHP 中国語 Web サイトの他の関連記事に注目してください。

推奨書籍:

React と TypeScript および Mobx を組み合わせる手順の詳細な説明

React-router v4 を使用する手順の詳細な説明

以上がPromiseA+の導入手順を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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