在JavaScript的世界中,所有代码都是单线程执行的。
由于这个“缺陷”,导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行。异步执行可以用回调函数实现:
function callback() {
console.log('Done');
}
console.log('before setTimeout()');
setTimeout(callback, 1000); // 1秒钟后调用callback函数
console.log('after setTimeout()');
可看见执行顺序为before setTimeout() 和 after setTimeout() 和 done 是异步执行的。
我们可以用promise来修改这一函数 promise有两个方法resolve和reject,将异步调用理得更加明朗,易于理解。
resolve接收成功后的值,reject用于接收失败后的值,随后new 一个 promise后,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);
});
可见promise的最大好处便是在异步执行的流程中,把执行代码和处理结果的代码分离./
比如有若干个任务,先做任务1,再做任务2,成功后再做任务3
用链串的方法。
function multiply(input) {
return new Promise(function (resolve, reject) {
console.log('calculating ' + input + ' x ' + input + '...');
setTimeout(resolve, 500, input * input);
});
}
// 0.5秒后返回input+input的计算结果:
function add(input) {
return new Promise(function (resolve, reject) {
console.log('calculating ' + input + ' + ' + input + '...');
setTimeout(resolve, 500, input + input);
});
}
var p = new Promise(function (resolve, reject) {
console.log('start new Promise...');
resolve(123);
});
p.then(multiply)
.then(add)
.then(function (result) {
console.log('Got value: ' + result);
});
查看输出