Promise 基本点

Promise 基本用法

创建 Promise

var promise = new Promise(function(resolve, reject){
  // do something async
  if(/* everything ok */){
    resolve("OK"); // it will return Promise.resolve("OK"), and the downstream will get "OK" as params
  } else {
    reject(Error("Error")); // it will return Error("Error") and the downstream will get Error("Error") as params
  }
})
`</pre>

Promise 构造器接受一个函数作为参数, 传入两个回调函数resolve 和 reject, 在这个函数参数中做一些一步操作, 成功后调用 resolve 将 Promise 对象的状态设置为 resolved 并返回一个 Promise 对象用于链式调用, 失败后调用 reject 将 Promise 对象的状态设置为 rejected 并返回一个 Promise 对象用于链式调用

使用时:

<pre>`promise.then(function(result){}).catch(function(err){})

Promise API Reference

静态方法:

  • Promise.resolve(promise), 返回一个 Promise

  • Promise.resolve(thenable), 从 thenable 对象创建一个新的 Promise, 一个 thenable (类 Promise) 对象是一个带有” then” 方法的对象.

  • Promise.resolve(obj), 创建一个以 obj 为肯定结果的 Promise

  • Promise.reject(obj), 创建一个以 obj 为否定结果的 Promise, 为了一致性和调试方便, obj 应该是一个 Error 实例对象.

  • Promise.all(array), 创建一个 Promise, 当且仅当数组中的所有 Promise 都 resolved 之后才设为 resolved, 若其中存在 rejected, 则设置状态为rejected

  • Promise.race(array), 创建一个 Promise, 当数组首先出现 resovled 或 rejected 的时候设置为同状态

Redux-Promise

npm install --save redux-promise
`</pre>

<pre>`import promiseMiddleWare from 'redux-promise'
`</pre>

The default export is a middleware function. If it receives a promise, it will dispatch the resolved value of the promise.

It will not dispatch anything if the promise rejects.

If it receives an Flux Standard Action whose `payload` is a promise, it will either:
  • dispatch a copy of the action with the resolved value of the promise, and set status to success
  • dispatch a copy of the action with the rejected value of the promise and set the status to error

    The middleware returns a promise to the caller so that it can wait for the operation to finish before continuing. This is especially useful for server-side rendering. If you find that a promise is not being returned, ensure that all middleware before it in the chain is also returning its next() call to the caller.

    Using in combination with redux-actions

    Because it supports FSA actions, you can use redux-promise in combination with redux-actions

    createAction(FETCH_DATA`, async id => {
    const result = await somePromise;
    return result.someValue
    });

Promise in ES6

在 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'
});
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×