标签:原来 foo source 解决方案 hello 作用 函数写法 异步编程 回调
一.promise含义
1.三种状态:进行中,成功,失败。(1)只有结果才能决定哪种状态,(2)一旦状态变成成功或者失败,就不会再变。
2.异步编程解决方案。
二:Promise实例
const promise = new Promise(function(resolve, reject) { var name="你好"; if (true){ resolve(name); } else { reject(error); } }); promise.then(function(value) { console.log(value) }, function(error) { // failure });
三:简单对象
function timeout(ms) { return new Promise((resolve, reject) => { setTimeout(resolve, ms, ‘done‘); }); } timeout(100).then((value) => { console.log(value); });
四:Promise.protoype.then();
then
方法返回的是一个新的Promise
实例(注意,不是原来那个Promise
实例)。因此可以采用链式写法,即then
方法后面再调用另一个then
方法。
getJSON("/posts.json").then(function(json) { return json.post; }).then(function(post) { // ... });
五:Promise.protoype.catch();
Promise.prototype.catch
方法是.then(null, rejection)
的别名,用于指定发生错误时的回调函数。
// bad promise .then(function(data) { // success }, function(err) { // error }); // good promise .then(function(data) { //cb // success }) .catch(function(err) { // error });
上面代码中,第二种写法要好于第一种写法,理由是第二种写法可以捕获前面then
方法执行中的错误,也更接近同步的写法(try/catch
)。因此,建议总是使用catch
方法,而不使用then
方法的第二个参数
六:Promise.protoype.finally();
finally
方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。
promise .then(result => {···}) .catch(error => {···}) .finally(() => {···});
七:Promise.all();
1.Promise.all
方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.all([p1, p2, p3]);
2.p接受一个数组,如果数组中有不是promise实例的,就先转化成promise实例。
3.p的状态由p1,p2,p3决定,分成两种。
(1)全部都是成功。p就是成功。此时p1,p2,p3的返回值组成的一个数组,传递给p的回调函数。
(2)只要这个数组中有一个被rejected,p的状态就变成rejected。此时第一个被rejected的实例的返回值,会传递给p的回调函数。
// 生成一个Promise对象的数组 const promises = [2, 3, 5, 7, 11, 13].map(function (id) { return getJSON(‘/post/‘ + id + ".json"); }); Promise.all(promises).then(function (posts) { // ... }).catch(function(reason){ // ... });
上面代码中,promises
是包含 6 个 Promise 实例的数组,只有这 6 个实例的状态都变成fulfilled
,或者其中有一个变为rejected
,才会调用Promise.all
方法后面的回调函数。
八:Promise.race();
Promise.race
方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.race([p1, p2, p3]);
上面代码中,只要p1
、p2
、p3
之中有一个实例率先改变状态,p
的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p
的回调函数。
const p = Promise.race([ fetch(‘/resource-that-may-take-a-while‘), new Promise(function (resolve, reject) { setTimeout(() => reject(new Error(‘request timeout‘)), 5000) }) ]); p .then(console.log) .catch(console.error); 上面代码中,如果 5 秒之内fetch方法无法返回结果,变量p的状态就会变为rejected,从而触发catch方法指定的回调函数。
上面代码中,如果 5 秒之内fetch
方法无法返回结果,变量p
的状态就会变为rejected
,从而触发catch
方法指定的回调函数。
九:Promise.resolve();
1.有时需要将现有对象转为 Promise 对象,Promise.resolve
方法就起到这个作用。
Promise.resolve(‘foo‘) // 等价于 new Promise(resolve => resolve(‘foo‘))
Promise.resolve
方法的参数分成四种情况。
(1)参数是一个 Promise 实例
如果参数是 Promise 实例,那么Promise.resolve
将不做任何修改、原封不动地返回这个实例。
(2)参数是一个thenable
对象
thenable
对象指的是具有then
方法的对象,比如下面这个对象。
let thenable = { then: function(resolve, reject) { resolve(42); } }; Promise.resolve方法会将这个对象转为 Promise 对象,然后就立即执行thenable对象的then方法。 let thenable = { then: function(resolve, reject) { resolve(42); } }; let p1 = Promise.resolve(thenable); p1.then(function(value) { console.log(value); // 42 });
(3)参数不是具有then
方法的对象,或根本就不是对象
如果参数是一个原始值,或者是一个不具有then
方法的对象,则Promise.resolve
方法返回一个新的 Promise 对象,状态为resolved
。
const p = Promise.resolve(‘Hello‘); p.then(function (s){ console.log(s) });
(4)不带有任何参数
Promise.resolve
方法允许调用时不带参数,直接返回一个resolved
状态的 Promise 对象。
所以,如果希望得到一个 Promise 对象,比较方便的方法就是直接调用Promise.resolve
方法。
const p = Promise.resolve(); p.then(function () { // ... });
十:Promise.reject();
Promise.reject(reason)
方法也会返回一个新的 Promise 实例,该实例的状态为rejected
。
const p = Promise.reject(‘出错了‘); // 等同于 const p = new Promise((resolve, reject) => reject(‘出错了‘)) p.then(null, function (s) { console.log(s) }); // 出错了
注意,Promise.reject()
方法的参数,会原封不动地作为reject
的理由,变成后续方法的参数。这一点与Promise.resolve
方法不一致。
const thenable = { then(resolve, reject) { reject(‘出错了‘); } }; Promise.reject(thenable) .catch(e => { console.log(e === thenable) }) // true
上面代码中,Promise.reject
方法的参数是一个thenable
对象,执行以后,后面catch
方法的参数不是reject
抛出的“出错了”这个字符串,而是thenable
对象。
十一:区分同步异步Promise.try()
1.asyns函数写法
const f = () => console.log(‘now‘); (async () => f())(); console.log(‘next‘);
上面代码中,第二行是一个立即执行的匿名函数,会立即执行里面的async
函数,因此如果f
是同步的,就会得到同步的结果;如果f
是异步的,就可以用then
指定下一步,就像下面的写法。
需要注意的是,async () => f()
会吃掉f()
抛出的错误。所以,如果想捕获错误,要使用promise.catch
方法。
(async () => f())() .then(...) .catch(...)
2.使用new Promise()
。
const f = () => console.log(‘now‘);
(
() => new Promise(
resolve => resolve(f())
)
)();
console.log(‘next‘);
使用Promise.try代替上面的写法
const f = () => console.log(‘now‘); Promise.try(f); console.log(‘next‘);
function getUsername(userId) { return database.users.get({id: userId}) .then(function(user) { return user.name; }); }
上面代码中,database.users.get()
返回一个 Promise 对象,如果抛出异步错误,可以用catch
方法捕获,就像下面这样写。
database.users.get({id: userId}) .then(...) .catch(...)
但是database.users.get()
可能还会抛出同步错误(比如数据库连接错误,具体要看实现方法),这时你就不得不用try...catch
去捕获。
try { database.users.get({id: userId}) .then(...) .catch(...) } catch (e) { // ... }
上面这样的写法就很笨拙了,这时就可以统一用promise.catch()
捕获所有同步和异步的错误。
Promise.try(database.users.get({id: userId})) .then(...) .catch(...)
标签:原来 foo source 解决方案 hello 作用 函数写法 异步编程 回调
原文地址:https://www.cnblogs.com/MJ-MY/p/9009503.html