88520191 2019-12-17
var getData = function(url) { var promise = new Promise(function(resolve, reject){ var client = new XMLHttpRequest(); // 封装请求对象 client.open("GET", url); client.onreadystatechange = handler; client.responseType = "json"; client.setRequestHeader("Accept", "application/json"); client.send(); function handler() { if (this.readyState !== 4) { return; } if (this.status === 200) { resolve(this.response); // 请求成功执行 } else { reject(new Error(this.statusText)); // 请求失败执行 } }; }); return promise; }; getData("/posts/info") .then( function(json) {console.log('Contents: ' + json);}, function(error) {console.error('出错了', error);} );
ES6规定,Promise对象是一个构造函数,用来生成Promise实例。
reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从Pending变为Rejected),在异步操作失败时调用并将异步操作报出的错误,作为参数传递出去。
var promise = new Promise(function(resolve, reject) { if (true){ resolve(value); } else { reject(error); } });
//第一个then方法指定的回调函数,返回的是另一个Promise对象。 //第二个then方法指定的回调函数,就会等待这个新的Promise对象状态发生变化。 //如果变为Resolved,就调用funcA,如果状态变为Rejected,就调用funcB。 getData("/get/info") .then(function(get) {return getData(get.commentURL);}) .then( function funcA(comments) {console.log("Resolved: ", comments);}, function funcB(err){console.log("Rejected: ", err);} ); //箭头函数简写 getData("/get/info") .then( get => getData(get.commentURL )) .then( comments => console.log("Resolved: ", comments), err => console.log("Rejected: ", err) );
Promise.prototype.catch方法是.then(null, rejection)的别名
用于指定发生错误时的回调函数。
then方法指定的回调函数,如果运行中抛出错误也会被catch方法捕获。
p.then((val) => console.log("fulfilled:", val)) .catch((err) => console.log("rejected:", err)); // 等同于 p.then((val) => console.log("fulfilled:", val)) .then(null, (err) => console.log("rejected:", err));
Promise对象的回调链,不管以then方法还是catch方法结尾,要是最后一个方法抛出错误,都可能无法捕捉到(因为Promise内部的错误不会冒泡到全局)
提供一个done方法,总是处于回调链的尾端,保证抛出任何可能出现的错误。
Promise.prototype.done = function (onFulfilled, onRejected) { this.then(onFulfilled, onRejected) .catch(function (err) { // 抛出一个全局错误 setTimeout(() => { throw err }, 0); }); };