在 JavaScript 世界中, 所有代码都是单线程执行的

异步执行可以可以用回调函数实现

function callback() {
  console.log('Done');
}
console.log('before setTimeout()');
setTimeout(callback, 1000);
console.log('after setTimeout()');
`</pre>

先看一个简单的 Promise 例子: 生成0-2之间的随机数, 如果小于1, 则等待一段时间后返回成功, 否则返回失败

<pre>`function test(resolve, reject){
  var timeOut = Math.random() * 2;
  log('set timeout to: ' + timeOut + ' seconds.');
  setTimeout(function(){
    if(timeOut &lt; 1) {
      log('call resolve()...');
      resolve('200 ok');
    } else {
      log('call reject()...');
      reject('timeout in ' + timeOut + ' seconds');
    }
  }, timeOut * 1000)
}
`</pre>

这个`test()`函数有两个参数, 这两个参数都是函数, 如果执行成功, 我们将调用`resolve('200 ok)'`, 如果执行失败, 我们将调用`reject('timeout in ' + timeOut + ' seconds.')`. 可以看出, `test()`函数只关心自己的逻辑, 并不关心具体的`resolve` 和`reject` 将如何处理.

有了执行函数, 我们就可以用一个 Promise 对象来执行他, 并在将来某个时刻获得成功或失败的结果

<pre>`var p1 = new Promsie(test);
var p2 = p1.then(function(result){
  console.log('成功: ' + result);
});
var p3 = p2.catch(function(err){
  console.log('失败: ' + err);
});
`</pre>

变量`p1`是一个 Promise 对象, 他负责执行执行`test`函数, 由于`test`函数在内部是异步执行的, 当`test`函数执行到`resolve('ok 200')`时, 告诉 Promsie 对象执行

<pre>`.then(function(result){ // result 是通过 test 传递给 resolve 的参数
  console.log('成功: ' + result);
});
`</pre>

当`test`执行到`reject`的时候, 告诉 Promise 对象执行

<pre>`.catch(function(err){ // err 是 test 传递给 reject 的参数
  console.log('失败: '+ err);
});
`</pre>

Promise 对象可以串联起来(因为都返回一个 Promise 对象)

<pre>`new Promise(test).then(function(result){console.log(result)}).catch(function(err){console.log(err)});
`</pre>

可见, Promise 最大的好处, 是在异步执行的流程中, 把执行代码和处理结果代码清晰地分离了.

Promise 还可以做更多的事情, 比如有若干个异步任务, 需要先做任务1, 如果成功后再做任务2, 任何任务失败则不再继续并执行错误处理函数

要串行执行这样的异步任务, 只需要链式调用

<pre>`job1.then(job2).then(job3).catch(handleError);
`</pre>

其中 job1, job2, job3 都是(或返回) Promise 对象

<pre>`function job2(input){
  return new Promise(function(resolve, reject){
      ....
    })
}
`</pre>

### 并行执行异步任务

试想一个页面聊天任务, 我们需要从两个不同的 URL 分别获取用户的个人信息和好友列表, 这两个任务是可以并行执行的, 用`Promise.all()`实现如下:

<pre>`var p1 = new Promise(function(resolve, reject){
  setTimeout(resolve, 500, 'P1');
});

var p2 = new Promise(function(resolve, reject) {
  setTimeout(resolve, 600, 'P2');
});

// 同时执行p1 和 p2, 并在他们都执行完毕后执行 then
Promise.all([p1,p2]).then(function(results){
  console.log(results); // 获得一个 Array: ['P1', 'P2']
});
`</pre>

有时多个异步任务是为了容错, 比如同时向两个 URL 读取, 只需要获得先返回的结果, 这种情况下用`Promise.race()`实现:

<pre>`var p1 = new Promise(function(resolve, reject){
  setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function(resolve, reject){
  setTimeout(resolve, 600, 'P2');
});

Promise.race([p1,p2]).then(function(result){
  console.log(result); // 'P1'
});