Javascript的世界是单线程的,由此衍生了许多问题需要用异步解决,比如网络操作和浏览器事件。
以前这样的问题往往通过回调或AJAX解决,但 ES6 之后,Promise被列入语法规范,浏览器统一执行。
Promise
如果我们要用 AJAX 进行异步操作,可写作如下形式:
request.onreadystatechange = function () {
if (request.readyState === 4) {
if (request.status === 200) {
return success(request.responseText);
} else {
return fail(request.status);
}
}
}
这么写 success 和 fail 都很明了,但当我需要多次异步操作时,就很难复用这段代码,每次 success, fail 的判定都是不一样的,需要整段复制。
Promise的基本形式可如: return new Promese(resolve,reject)=>{})
resolve 等同于 success
reject 等同于 fail
then(), catch()
借用廖雪峰老师的这段代码:
// 执行函数
function test(resolve, reject) {
var timeOut = Math.random() * 2;
log('set timeout to: ' + timeOut + ' seconds.');
setTimeout(function () {
if (timeOut < 1) {
log('call resolve()...');
resolve('200 OK');
}
else {
log('call reject()...');
reject('timeout in ' + timeOut + ' seconds.');
}
}, timeOut * 1000);
}
// Promise 对象
var p1 = new Promise(test);
var p2 = p1.then(function (result) {
console.log('成功:' + result);
});
var p3 = p2.catch(function (reason) {
console.log('失败:' + reason);
});
首先创建一个执行函数,写好 resolve 和 reject 的条件。
随后我们创建一个 Promise 对象,如果函数成功,使用 then()继续执行下一步。如果函数失败,则通过 catch() 抓住 error。
拼合之后:
new Promise(test).then(function (result) {
console.log('成功:' + result);
}).catch(function (reason) {
console.log('失败:' + reason);
});
Promise.all()
Promise.all() 方法接收一个 promise 的 iterable 类型(注:Array,Map,Set都属于ES6的 iterable 类型)的输入,该方法的作用是将多个Promise对象实例包装,生成并返回一个新的Promise实例。
promise 数组中所有的 promise 实例都变为 resolve 的时候,该方法才会返回,并将所有结果传递 results 数组中。promise 数组中任何一个 promise 为 reject 的话,则整个 Promise.all 调用会立即终止,并返回一个 reject 的新的 promise 对象。
let p1 = Promise.resolve(1),
p2 = Promise.reject(2),
p3 = Promise.resolve(3);
Promise.all([p1, p2, p3]).then(function (results) {
//then方法不会被执行
console.log(results);
}).catch(function (e){
//catch方法将会被执行,输出结果为:2
console.log(2);
});
Promise.race()
Promise.race() 方法接收一个 promise 的 iterable 类型(注:Array,Map,Set都属于ES6的 iterable 类型)的输入,如果其中任意一个 promise 执行成功,返回 resolve 或者 reject, Promise.race() 也将返回 resolve 或者 reject。
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'one');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'two');
});
Promise.race([promise1, promise2]).then((value) => {
console.log(value);
// Both resolve, but promise2 is faster
});
如上所示,promise1 与 promise2 进行竞速,100ms < 500ms,则 promise2 被返回。