- Promise 对象的定义
- ES6 原生提供 Promise 对象。所谓 Promise 对象,就是代表了某个将要发生的事件(通常是一个异步操作)。
- 它的好处在于,有了 Promise 对象,就可以将异步操作以同步操作的流程表示出来,避免了层层嵌套的回调函数。
- ES6 的 Promise 对象是一个构造函数,用来生成 Promise 实例。
var promise = new Promise(function(resolve, reject){
if(/* 异步操作成功 */){
resolve(value);
}else{
reject(error);
}
})
promise.then(function(value){
// success
},function(error){
// failure
})
- Promise.then () 方法 【promise.then(onFulfilled, onRejected);】
- Promise 构造函数接受一个函数作为参数,该函数的两个参数分别为 resolve 和 reject 方法。如果异步操作成功,则用resolve 方法将 Promise 对象的状态变为“成功”(即从 pending 变为 resolved );如果异步操作失败,则用 reject 方法将状态变为"失败"(即从 pending 变为 rejected )。
- promise 实例生成后,可以用 then 方法分别指定 resolve 方法和 reject 方法的回调函数。
- 链式调用:then 方法返回的是一个新的 Promise 对象,因此可以采用链式写法。
var promise = new Promise(function(resolve, reject){
resolve("传递给then的值");
});
promise.then(function (value) {
console.log(value);
}, function (error) {
console.error(error);
});
- Promise.catch () 方法 【promise.catch(onRejected);】
- catch 方法:捕捉错误。catch 方法是 then(null,rejection) 的别名,用于指定发生错误时的回调函数。
- Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。
var promise = new Promise(function(resolve, reject){
resolve("传递给then的值");
});
promise.then(function (value) {
console.log(value);
}).catch(function (error) {
console.error(error);
});
- Promise.resolve () 方法 【Promise.resolve(promise) / Promise.resolve(thenable) / Promise.resolve(object)】
Promise.resolve 可以把普通对象转换为 Promise 对象。如果 Promise.resolve 方法的参数不是具有 then 方法的对象(又称thenable 对象),则返回一个新的 Promise 对象,且他的状态为 resolve。
- Promise.resolve(promise); 接收到 promise 对象参数的时候,返回的还是接收到的 promise 对象。
- Promise.resolve(thenable); 接收到 thenable 类型的对象时候,返回一个新的 promise 对象,这个对象具有一个 then 方法。
- Promise.resolve(object); 接收参数为其他类型的时候(包括JavaScript对或null等)返回一个将该对象作为值的新 promise 对象。
// 将 jQuery 生成的 deferred 对象,转换为一个新的 ES6 的 Promise 对象。
var jsPromise = Promise.resolve($.ajax('/whatever.json'));
// 会生成一个新的Promise对象,他的状态为fulfilled,所以回调函数会立即执行,Promise.resolve方法的参数就是回调函数的参数。
var p = Promise.resolve('hello');
p.then(function(s){
console.log(s);// hello
})
/* ========================================== */
var taskName = "task 1"
asyncTask(taskName).then(function (value) {
console.log(value);
}).catch(function (error) {
console.error(error);
});
function asyncTask(name){
return Promise.resolve(name).then(function(value){
return "Done! "+ value;
});
}
- Promise.reject () 方法 【Promise.reject(object)】
Promise.reject 类似,不同点在于,即使 Promise.reject 接收到的参数是一个 promise 对象,该函数也还是会返回一个全新的 promise 对象。
var r = Promise.reject(new Error("error"));
console.log(r === Promise.reject(r)); // false
- Promise.all () 方法 【Promise.all(promiseArray);】
生成并返回一个新的 promise 对象。参数传递 promise 数组中所有的 promise 对象都变为 resolve 的时候,该方法才会返回, 新创建的 promise 则会使用这些 promise 的值。如果参数中的任何一个 promise 为 reject 的话,则整个 Promise.all 调用会立即终止,并返回一个 reject 的新的 promise 对象。由于参数数组中的每个元素都是由 Promise.resolve 包装(wrap)的,所以 Promise.all 可以处理不同类型的 promose 对象。
// 生成一个 Promise 对象的数组
var promises = [2, 3, 4, 6, 8, 26].map(function(id){
return getJSON("/post"+ id + ",json");
});
Promise.all(promises).then(function(posts){
// ...
}).catch(function(reason){
// ...
})
/* ================================= */
var p1 = Promise.resolve(1),
p2 = Promise.resolve(2),
p3 = Promise.resolve(3);
Promise.all([p1, p2, p3]).then(function (results) {
console.log(results); // [1, 2, 3]
});
- Promise.race () 方法 【Promise.race(promiseArray);】
生成并返回一个新的 promise 对象。参数 promise 数组中的任何一个 promise 对象如果变为 resolve 或者 reject 的话, 该函数就会返回,并使用这个 promise 对象的值进行 resolve 或者 reject。
var p1 = Promise.resolve(1),
p2 = Promise.resolve(2),
p3 = Promise.resolve(3);
Promise.race([p1, p2, p3]).then(function (value) {
console.log(value); // 1
});
- async 函数 【ES7_ async & await】
async 函数是用来取代回调函数的另一种方法。只要函数名之前加上 async 关键字,就表明该函数内部有异步操作。改异步操作应该返回一个 Promise 对象,前面用 await 关键字注明。当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句。
// async 和 await
function timeout(ms){
return new Promise(resolve => {
setTimeout(resolve,ms);
})
}
async function value(value){
await timeout(50);
return value;
}
- 用 Promise 对象实现 Ajax 操作实例
var getJSON = function(url){
var promise = new Promise(function(resolve,reject){
var xhr = new XMLHttpRequest();
xhr.open("GET",url);
xhr.onreadystatechange = handler;
xhr.responseType = 'json';
xhr.setRequestHeader("Accept","application/json");
xhr.send();
function handler(){
if(this.readyState === this.DONE){
if(this.status === 200){
resolve(this.response);
}else{
reject(this);
}
}
}
})
return promise;
}
getJSON("/posts.json").then(function(json){
// continue
},function(error){
// handle errors
})
/* ======================== 链式调用*/
getJSON ("/posts.json").then(function(json){
return json.post;
}).then(function(post){
// proceed
})
/* ======================== catch 方法 */
getJSON("/posts.json").then(function(posts){
return getJSON(post.commentURL)
}).then(function(comments){
// some code
}).catch(function(error){
// 处理前两个回调函数运行时发生的错误。
console.log('发生错误!',error)
})