《你不知道的Javascript--中卷 学习总结》(异步、promise)

异步

一、任什么时候候,只要把一段代码包装成一个函数,并指定它在响应某个事件(定时器、鼠标点 击、Ajax 响应等)时执行,你就是在代码中建立了一个未来执行的块。ajax

二、多数状况下,代码在开发者工具的控制台中输出的对象表示与指望是一致的。可是, 下面这段代码运行的时候,浏览器可能会认为须要把控制台 I/O 延迟到后台,在这种状况下, 等到浏览器控制台输出对象内容时,a.index++ 可能已经执行,所以会显示 { index: 2 }。数组

var a = {
          index: 1
    };
    // 而后
    console.log( a ); // 2
    // 再而后 
    a.index++;
复制代码

三、并发交互模式promise

  • 根据返回的特性标识处理,根据不一样的url来存放在数组的不一样位置。
var res = [];
    function response(data) {
      if (data.url == "http://some.url.1") {
          res[0] = data;
      }
      else if (data.url == "http://some.url.2") {
          res[1] = data;
    } }
    // ajax(..)是某个库中提供的某个Ajax函数
    ajax( "http://some.url.1", response );
    ajax( "http://some.url.2", response );
复制代码
  • 两个值所有存在,在进行函数调用(门闩)
var a, b;
    function foo(x) {
         a = x * 2;
         if (a && b) {
             baz();
    } }
    function bar(y) {
         b = y * 2;
         if (a && b) {
             baz();
    } }
    function baz() {
        console.log( a + b );
    }
    // ajax(..)是某个库中的某个Ajax函数 
    ajax( "http://some.url.1", foo ); 
    ajax( "http://some.url.2", bar );

复制代码
  • 只要其中一个执行
var a;
    function foo(x) {
        if (!a) {
            a = x * 2;
            baz();
        }
    }
    function bar(x) {
        if (!a) {
            a = x / 2;
            baz(); 
        }
    }
    function baz() {
        console.log( a );
    }
    // ajax(..)是某个库中的某个Ajax函数 
    ajax( "http://some.url.1", foo ); 
    ajax( "http://some.url.2", bar );
复制代码

Promise

检测promise类型(检测是否认义thenable)

if (
         p !== null &&
         (
             typeof p === "object" ||
             typeof p === "function"
    ) &&
    typeof p.then === "function" ){
    // 假定这是一个thenable! }
    else {
    // 不是thenable
    }
复制代码

Promise API 概述

  • new Promise(..) 构造器

一、有启示性的构造器 Promise(..) 必须和 new 一块儿使用,而且必须提供一个函数回调。这个 回调是同步的当即调用的。这个函数接受两个函数回调,用以支持 promise 的决议。通 常咱们把这两个函数称为resolve(..)reject(..)浏览器

var p = new Promise( function(resolve,reject){ 
    // resolve(..)用于决议/完成这个promise
    // reject(..)用于拒绝这个promise
    } );
复制代码

二、reject(..) 就是拒绝这个 promise;但 resolve(..) 既可能完成 promise,也可能拒绝,要 根据传入参数而定。若是传给 resolve(..) 的是一个非 Promise非 thenable 的当即值,这 个 promise 就会用这个值完成bash

三、若是传给 resolve(..) 的是一个真正的 Promise 或 thenable 值,这个值就会被递归展 开,而且(要构造的)promise 将取用其最终决议值或状态。并发

  • Promise.resolve(..) 和 Promise.reject(..)

一、建立一个已被拒绝的 Promise 的快捷方式是使用 Promise.reject(..),因此如下两个 promise 是等价的异步

var p1 = new Promise( function(resolve,reject){
         reject( "Oops" );
     } );
     var p2 = Promise.reject( "Oops" );
复制代码

二、Promise.resolve(..) 会展开 thenable 值(前面已屡次介绍)。在这种状况 下,返回的 Promise 采用传入的这个 thenable 的最终决议值,多是完成,也多是拒绝函数

var fulfilledTh = {
        then: function(cb) { cb( 42 ); }
    };
    var rejectedTh = {
        then: function(cb,errCb) {
            errCb( "Oops" );
    } };
     var p1 = Promise.resolve( fulfilledTh );
     var p2 = Promise.resolve( rejectedTh );
    // p1是完成的promise 
    // p2是拒绝的promise
复制代码

三、若是传入的是真正的 Promise,Promise.resolve(..) 什么都不会作,只会直接 把这个值返回工具

  • then(..) 和 catch(..)

一、每一个 Promise 实例(不是 Promise API 命名空间)都有 then(..) 和 catch(..) 方法,经过 这两个方法能够为这个 Promise 注册完成和拒绝处理函数url

二、then(..) 接受一个或两个参数:第一个用于完成回调,第二个用于拒绝回调。若是二者中 的任何一个被省略或者做为非函数值传入的话,就会替换为相应的默认回调。默认完成回 调只是把消息传递下去,而默认拒绝回调则只是从新抛出(传播)其接收到的出错缘由。

三、catch(..) 只接受一个拒绝回调做为参数,并自动替换默认完成 回调。换句话说,它等价于 then(null,..)

p.then( fulfilled );
    p.then( fulfilled, rejected );
    p.catch( rejected ); // 或者p.then( null, rejected )
复制代码

四、then(..) 和 catch(..) 也会建立并返回一个新的 promise,这个 promise 能够用于实现 Promise 链式流程控制。若是完成或拒绝回调中抛出异常,返回的 promise 是被拒绝的。如 果任意一个回调返回非 Promise、非 thenable 的当即值,这个值会被用做返回 promise 的完 成值。若是完成处理函数返回一个 promise 或 thenable,那么这个值会被展开,并做为返回 promise 的决议值。

  • Promise.all([ .. ]) 和 Promise.race([ .. ])

一、ES6PromiseAPI静态辅助函数Promise.all([ .. ])和Promise.race([ .. ])都会建立一 个 Promise 做为它们的返回值。这个 promise 的决议彻底由传入的 promise 数组控制。

二、对Promise.all([ .. ])来讲,只有传入的全部promise都完成,返回promise才能完成。 若是有任何 promise 被拒绝,返回的主 promise 就当即会被拒绝(抛弃任何其余 promise 的 结果)。若是完成的话,你会获得一个数组,其中包含传入的全部 promise 的完成值。对于 拒绝的状况,你只会获得第一个拒绝 promise 的拒绝理由值。

三、对Promise.race([ .. ])来讲,只有第一个决议的promise(完成或拒绝)取胜,而且其 决议结果成为返回 promise 的决议。

var p1 = Promise.resolve( 42 );
     var p2 = Promise.resolve( "Hello World" );
     var p3 = Promise.reject( "Oops" );
     Promise.race( [p1,p2,p3] )
    .then( function(msg){
        console.log( msg );
    } );
    Promise.all( [p1,p2,p3] )
    .catch( function(err){
        console.error( err );
    } );
    Promise.all( [p1,p2] )
    .then( function(msgs){
        console.log( msgs );
    } );
    // 42
    // "Oops"
    // [42,"Hello World"]
复制代码

四、若向Promise.all([ .. ])传入空数组,它会当即完成,但Promise. race([ .. ]) 会挂住,且永远不会决议。

相关文章
相关标签/搜索