同步编程通常来说易于调试和维护,然而,异步编程通常能获得更好的性能和更大的灵活性。异步的最大特点是无需等待。“Promises”渐渐成为JavaScript里最重要的一部分,大量的新API都开始promise原理实现。下面让我们看一下什么是promise,以及它的API和用法!
Promises现状
XMLHttpRequest API是异步的,但它没有使用promise API。但有很多原生的 javascript API 使用了promise:
*Battery API
*fetch API (XHR的替代品)
*ServiceWorker API
Promises将来只会变得越来越流行、普遍,非常重要,所有的前端开发人员都将用到它。另一个值得注意的是,Node.js是基于Promises的平台(很显然,Promise是它的一个核心特征)。
Promises的用法比你想象的要简单——如果你以前喜欢使用setTimeout来控制异步任务的话!
Promise基本用法
new Promise()构造器可以用在传统的异步任务中,就像以前 setTimeout 和 XMLHttpRequest 的用法一样。一个新的 Promise 使用 new 关键字生成,同时,这个 Promises 提供了 resolve 和 reject 函数让我们执行回调操作:
var p = new Promise(function(resolve, reject) { // Do an async task async task and then... if(/* good condition */) { resolve('Success!'); } else { reject('Failure!'); }});p.then(function() { /* do something with the result */}).catch(function() { /* error */})
程序员可以手动的在回调函数内部根据执行情况调用 resolve 和 reject 函数。下面是一个比较具有现实意义的例子,它将一个 XMLHttpRequest 调用转换为 基于 Promises 的任务:
// From Jake Archibald's Promises and Back:// http://www.html5rocks.com/en/tutorials/es6/promises/#toc-promisifying-xmlhttprequestfunction 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(); });}// Use it!get('story.json').then(function(response) { console.log("Success!", response);}, function(error) { console.error("Failed!", error);});
Promise.resolve() 和 Promise.reject() 可以直接被调用。有时候,当判断出 promise 并不需要真正执行时,我们并不需要 使用 new 创建 Promise 对象,而是可以直接调用 Promise.resolve() 和 Promise.reject()。比如:
var userCache = {};function getUserDetail(username) { // In both cases, cached or not, a promise will be returned if (userCache[username]) { // Return a promise without the "new" keyword return Promise.resolve(userCache[username]); } // Use the fetch API to get the information // fetch returns a promise return fetch('users/' + username + '.json') .then(function(result) { userCache[username] = result; return result; }) .catch(function() { throw new Error('Could not find user: ' + username); });}
新闻热点
疑难解答
图片精选