标签:原来 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