Skip to content

Instantly share code, notes, and snippets.

@xgqfrms-GitHub
Created April 4, 2017 14:42
Show Gist options
  • Save xgqfrms-GitHub/9f845b7a9a8f1233e8e2fac33b2cb68a to your computer and use it in GitHub Desktop.
Save xgqfrms-GitHub/9f845b7a9a8f1233e8e2fac33b2cb68a to your computer and use it in GitHub Desktop.
JavaScript Promise
@xgqfrms-GitHub
Copy link
Author

xgqfrms-GitHub commented Apr 4, 2017

最基本的情况是,promise 有点类似于事件侦听器,但有以下两点区别:

promise 只能成功或失败一次,而不能成功或失败两次,也不能从成功转为失败或从失败转为成功。

如果 promise 已成功或失败,且您之后添加了成功/失败回调,则将会调用正确的回调,即使事件发生在先。

这对于异步成功/失败尤为有用,因为您可能对某些功能可用的准确时间不是那么关注,更多地是关注对结果作出的反应。

img1.ready().then(function() {
  // loaded
}, function() {
  // failed
});

// and…
Promise.all([img1.ready(), img2.ready()]).then(function() {
  // all loaded
}, function() {
  // one or more failed
});

https://blog.domenic.me/
https://html.spec.whatwg.org/#windows
https://github.com/domenic/promises-unwrapping/blob/master/docs/states-and-fates.md

Promise 有三个可能的互斥状态:履行,拒绝和待决。

https://tc39.github.io/ecma262/#sec-promise-objects
任何 Promise对象都是三个互斥状态之一:履行,拒绝和待处理:
fulfilled
rejected
pending

@xgqfrms-GitHub
Copy link
Author

xgqfrms-GitHub commented Apr 4, 2017

$ jQuery deferred.promise()

https://api.jquery.com/category/deferred-object/
https://api.jquery.com/Types/#Promise

https://thewayofcode.wordpress.com/tag/jquery-deferred-broken/

创建一个延迟并设置两个基于定时器的函数来解析或拒绝随机间隔后的延迟。

function asyncEvent() {
  var dfd = jQuery.Deferred();
 
  // Resolve after a random interval
  setTimeout(function() {
    dfd.resolve( "hurray" );
  }, Math.floor( 400 + Math.random() * 2000 ) );
 
  // Reject after a random interval
  setTimeout(function() {
    dfd.reject( "sorry" );
  }, Math.floor( 400 + Math.random() * 2000 ) );
 
  // Show a "working..." message every half-second
  setTimeout(function working() {
    if ( dfd.state() === "pending" ) {
      dfd.notify( "working... " );
      setTimeout( working, 500 );
    }
  }, 1 );
 
  // Return the Promise so caller can't change the Deferred
  return dfd.promise();
}
 
// Attach a done, fail, and progress handler for the asyncEvent
$.when( asyncEvent() ).then(
  function( status ) {
    alert( status + ", things are going well" );
  },
  function( status ) {
    alert( status + ", you fail this time" );
  },
  function( status ) {
    $( "body" ).append( status );
  }
);

使用目标参数将一个现有对象提升为一个Promise:

// Existing object
var obj = {
    hello: function( name ) {
      alert( "Hello " + name );
    }
  },
  // Create a Deferred
  defer = $.Deferred();
 
// Set object as a promise
defer.promise( obj );
 
// Resolve the deferred
defer.resolve( "John" );
 
// Use the object as a Promise
obj.done(function( name ) {
  obj.hello( name ); // Will alert "Hello John"
}).hello( "Karl" ); // Will alert "Hello Karl"

@xgqfrms-GitHub
Copy link
Author

xgqfrms-GitHub commented Apr 4, 2017

generators + promises = tasks

http://taskjs.org/

尽管 promise 实现遵照标准化行为,但其整体 API 有所不同。
JavaScript promise 在 API 中类似于 RSVP.js
下面是创建 promise 的步骤:

let promise = new Promise(function(resolve, reject) {
  // do a thing, possibly async, then…

  if (/* everything turned out fine */) {
    resolve("Stuff worked!");
  }
  else {
    reject(Error("It broke"));
  }
});

Promise 构造函数包含一个参数和一个带有 resolve(解析)和 reject(拒绝)两个参数的回调。
在回调中执行一些操作(例如异步),如果一切都正常,则调用 resolve,否则调用 reject。

@xgqfrms-GitHub
Copy link
Author

xgqfrms-GitHub commented Apr 4, 2017

与普通旧版 JavaScript 中的 throw 一样,通常拒绝时会给出 Error 对象,但这不是必须的。
Error 对象的优点在于它们能够捕捉堆叠追踪,因而使得调试工具非常有用。

以下是有关 promise 的使用示例:

promise.then(function(result) {
  console.log(result); // "Stuff worked!"
}, function(err) {
  console.log(err); // Error: "It broke"
});

then() 包含两个参数:一个用于成功情形的回调和一个用于失败情形的回调。
这两个都是可选的,因此您可以只添加一个用于成功情形或失败情形的回调。

@xgqfrms-GitHub
Copy link
Author

xgqfrms-GitHub commented Apr 4, 2017

@xgqfrms-GitHub
Copy link
Author

@xgqfrms-GitHub
Copy link
Author

xgqfrms-GitHub commented Apr 4, 2017

对 XMLHttpRequest 执行 promise

旧 API 将更新为使用 promise,如有可能,采用后向兼容的方式。
XMLHttpRequest 是主要候选对象,不过,我们可编写一个作出 GET 请求的简单函数:

function get(url) {
  // Return a new promise.
  return new Promise(function(resolve, reject) {
    // Do the usual XHR stuff
    var req = new XMLHttpRequest();
    req.open('GET', url);

    req.onload = function() {
      // This is called even on 404 etc
      // so check the status
      if (req.status == 200) {
        // Resolve the promise with the response text
        resolve(req.response);
      }
      else {
        // Otherwise reject with the status text
        // which will hopefully be a meaningful error
        reject(Error(req.statusText));
      }
    };

    // Handle network errors
    req.onerror = function() {
      reject(Error("Network Error"));
    };

    // Make the request
    req.send();
  });
}

现在让我们来使用这一功能:

get('story.json').then(function(response) {
  console.log("Success!", response);
}, function(error) {
  console.error("Failed!", error);
})

https://github.com/googlesamples/web-fundamentals/blob/gh-pages/fundamentals/getting-started/primers/story.json

https://googlesamples.github.io/web-fundamentals/fundamentals/getting-started/primers/story.json

https://ufo-github.github.io/web-fundamentals/fundamentals/getting-started/primers/story.json

https://ufo-github.github.io/web-fundamentals/

@xgqfrms-GitHub
Copy link
Author

xgqfrms-GitHub commented Apr 4, 2017

es6-modules/readme.md

G:\wwwRoot\learning\es6-modules\readme.md

classlist

http://caniuse.com/#search=classlist

https://dom.spec.whatwg.org/#dom-element-classlist

https://developer.mozilla.org/zh-CN/docs/Web/API/Element/classList

Element.classList 是一个只读属性,返回一个元素的类属性的实时 DOMTokenList集合。

使用 classList 是一个方便的替代方法,通过element.className作为空格分隔的字符串访问元素的类列表。

https://developer.mozilla.org/zh-CN/docs/Web/API/Element/className

https://developer.mozilla.org/zh-CN/docs/Web/API/Element/getAttribute

https://developer.mozilla.org/zh-CN/docs/Web/API/Element/setAttribute

设置指定元素上的一个属性值。如果属性已经存在,则更新该值;
否则将添加一个新的属性用指定的名称和值。

要获取属性的当前值,使用 getAttribute();
要删除一个属性,调用removeAttribute()。

https://developer.mozilla.org/zh-CN/docs/Web/API/Element/className

className 获取并设置指定元素的class属性的值。

@xgqfrms-GitHub
Copy link
Author

https://developers.google.com/web/

https://developers.google.com/web/showcase/
https://developers.google.com/web/updates/
https://developers.google.com/web/tools/

https://developers.google.com/web/fundamentals/engage-and-retain/app-install-banners/
https://developers.google.com/web/fundamentals/engage-and-retain/push-notifications/

https://developers.google.com/web/tools/service-worker-libraries/
https://developers.google.com/web/fundamentals/getting-started/primers/service-workers

https://developers.google.com/web/fundamentals/engage-and-retain/
https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/

https://developers.google.com/web/fundamentals/discovery-and-monetization/
https://developers.google.com/web/fundamentals/native-hardware/fullscreen/

https://developers.google.com/web/fundamentals/native-hardware/click-to-call/

NIST Telephone Time-of-Day Service 
<a href="tel:+1-303-499-7111">+1 (303) 499-7111</a>

https://developers.google.com/web/fundamentals/native-hardware/capturing-images/

<input type="file" accept="image/*" capture>

https://developers.google.com/web/fundamentals/design-and-ui/animations/asymmetric-animation-timing
https://developers.google.com/web/fundamentals/design-and-ui/animations/animations-and-performance

https://developers.google.com/web/fundamentals/instant-and-offline/service-worker/registration
https://developers.google.com/web/fundamentals/instant-and-offline/service-worker/lifecycle
https://developers.google.com/web/fundamentals/getting-started/primers/service-workers

https://developers.google.com/web/fundamentals/security/encrypt-in-transit/why-https
https://developers.google.com/web/fundamentals/performance/http2/
https://developers.google.com/web/fundamentals/security/prevent-mixed-content/fixing-mixed-content
https://developers.google.com/web/fundamentals/security/prevent-mixed-content/what-is-mixed-content

@xgqfrms-GitHub
Copy link
Author

xgqfrms-GitHub commented Apr 4, 2017

ServiceWorker

http://caniuse.com/#search=ServiceWorker

Global 0% + 63.39% = 63.39%

https://jakearchibald.github.io/isserviceworkerready/

Web Workers

http://caniuse.com/#search=Worker
http://caniuse.com/#search=Web%20Workers

Global 94%

Shared Web Workers

Global 47.59%

FileReaderSync

Global 93.75%

@xgqfrms-GitHub
Copy link
Author

IndexedDB

https://developer.mozilla.org/zh-CN/docs/Web/API/IndexedDB_API

IndexedDB 是一种低级API用于客户端存储大量结构化数据(包括, 文件/ blobs)。
该API使用索引来实现对该数据的高性能搜索。
虽然 DOM 存储 对于存储较少量的数据很有用,但对于存储更大量的结构化数据来说,这种方法不太有用。
IndexedDB提供了一个解决方案。

@xgqfrms-GitHub
Copy link
Author

Web_Workers_API

https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API

Web Workers是一种机制,通过它可以使一个脚本操作在与Web应用程序的主执行线程分离的后台线程中运行。
这样做的优点是可以在单独的线程中执行繁琐的处理,让主(通常是UI)线程运行而不被阻塞/减慢。

使用 Web Workers

https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API/Using_web_workers

Worker

https://developer.mozilla.org/zh-CN/docs/Web/API/Worker/Worker

Worker() 构造函数创建一个 Worker 对象,该对象执行指定的URL脚本。
这个脚本必须遵守 同源策略 。
如果 此URL有一个无效的语句,或者违反同源策略,则会抛出一个 SECURITY_ERR 类型的DOMException 。

Worker.postMessage()

https://developer.mozilla.org/zh-CN/docs/Web/API/Worker/postMessage

Worker 接口的 postMessage()方法向worker的内部作用域发送一个消息。
这接受单个参数,这是要发送给worker的数据。
数据可以是由结构化克隆算法处理的任何值或JavaScript对象,其包括循环引用。

@xgqfrms-GitHub
Copy link
Author

xgqfrms-GitHub commented Apr 4, 2017

ServiceWorker

https://developer.mozilla.org/zh-CN/docs/Web/API/ServiceWorker

ServiceWorker API 的 ServiceWorker接口 提供一个对一个服务工作者的引用。
多个浏览上下文(例如页面,工作者等)可以与相同的服务工作者相关联,每个都通过唯一的ServiceWorker对象。

使用 Service Workers

https://developer.mozilla.org/zh-CN/docs/Web/API/Service_Worker_API/Using_Service_Workers

本文提供了有关开始使用 service workers所需的信息。
包括基本架构、注册一个service worker、一个新service worker的安装和激活过程、更新你的service worker、缓存控制和自定义响应,
这一切都在一个简单的具有离线功能的应用程序的上下文中。

https://serviceworke.rs/
https://github.com/mozilla/serviceworker-cookbook

@xgqfrms-GitHub
Copy link
Author

xgqfrms-GitHub commented May 16, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment