译者注: 处处是回调函数,代码非常痴肥难看, Promise 主要用来解决这种编程方法, 将某些代码封装于内部。
Promise 直译为“答理”,但一般直接称为 Promise;
代码的可读性非常重要,因为开发人员支出一般比计算机硬件的支出要大很多倍。
虽然同步代码更容易跟踪和调试, 但异步方法却具有更好的性能与灵活性.
怎样在同一时刻倡议多个请求, 然后分袂措置惩罚惩罚响应功效? Promise 现已成为 JavaScript 中非常重要的一个构成部分, 很多新的API都以 promise 的方法来实现。下面简要介绍 promise, 以及相应的 API 和使用示例!
XMLHttpRequest 是异步API, 但不算 Promise 方法。当前使用 Promise 的原生 api 包孕:
Promise 会越来越风行,所以前端开发需要快速掌握它们。固然, Node.js 是另一个使用 Promise 的平台(显然, Promise 在Node中是一个核心特性)。
测试 promises 可能比你想象的还要容易, 因为 setTimeout 可以用来看成异步“任务”!
Promise 根基用法直接使用 new Promise() 结构函数的方法, 应该只用来措置惩罚惩罚遗留的异步任务编程, 例如 setTimeout 或者 XMLHttpRequest。 通过 new 关键字创建一个新的 Promise 东西, 该东西有 resolve(搞定!) 和 reject(拒绝!) 两个回调函数:
var p = new Promise(function(resolve, reject) { // ... ... // 此处,可以执行某些异步任务,然后... // 在回调中,或者任何处所执行 resolve/reject if(/* good condition */) { resolve('传入成就功效信息,如 data'); } else { reject('掉败:原因...!'); } }); p.then(function(data) { /* do something with the result */ }).catch(function(err) { /* error :( */ });一般是由开发人员按照异步任务执行的功效,来手动挪用 resolve 或者 reject. 一个范例的例子是将 XMLHttpRequest 转换为基于Promise的任务:
// 本段示例代码来源于 Jake Archibald's Promises and Back: // #toc-promisifying-xmlhttprequest function get(url) { // 返回一个 promise 东西. return new Promise(function(resolve, reject) { // 执行通例的 XHR 请求 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("网络堕落")); }; // Make the request req.send(); }); }; // 使用! get('story.json').then(function(response) { console.log("Success!", response); }, function(error) { console.error("Failed!", error); });有时候在 promise 要领体中不需要执行异步任务 —— 固然,在有可能会执行异步任务的情况下, 返回 promise 将是最好的方法, 这样只需要给定功效措置惩罚惩罚函数就行。在这种情况下, 不需要使用 new 关键字, 直接返回 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); }); };因为总是会返回 promise, 所以只需要通过 then 和 catch 要领措置惩罚惩罚功效即可!
then每个 promise 实例都有 then 要领, 用来措置惩罚惩罚执行功效。 第一个 then 要领回调的参数, 就是 resolve() 传入的阿谁值:
new Promise(function(resolve, reject) { // 通过 setTimeout 模拟异步任务 setTimeout(function() { resolve(10); }, 3000); }) .then(function(result) { console.log(result); }); // console 输出的功效: // 10then 回调由 promise 的 resolved 触发。你也可以使用链式的 then` 回调要领:
new Promise(function(resolve, reject) { // 通过 setTimeout 模拟异步任务 setTimeout(function() { resolve(10); }, 3000); }) .then(function(num) { console.log('first then: ', num); return num * 2; }) .then(function(num) { console.log('second then: ', num); return num * 2; }) .then(function(num) { console.log('last then: ', num);}); // console 输出的功效: // first then: 10 // second then: 20 // last then: 40每个 then 收到的功效都是之前阿谁 then 返回的值。
如果 promise 已经 resolved, 但之后才能用 then 要领, 则当即触发还调。如果promise被拒绝之后才能用 then, 则回调函数不会被触发。
catch当 promise 被拒绝时, catch 回调就会被执行:
new Promise(function(resolve, reject) { // 通过 setTimeout 模拟异步任务 setTimeout(function() { reject('Done!'); }, 3000); }) .then(function(e) { console.log('done', e); }) .catch(function(e) { console.log('catch: ', e); }); // console 输出的功效: // 'catch: Done!'传入 reject 要领的参数由你本身决定。一般来说是传入一个 Error 东西:
reject(Error('Data could not be found')); Promise.all