IFE 2019年04月11日 分类: 前端知识体系 标签: javascript 浏览量: 4993
Promise 对象用于表示一个异步操作的最终状态(完成或失败),以及该异步操作的结果值。它可以使我们以同步的方式写异步代码。
它只有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。 只有异步操作的结果,可以决定当前是哪一种状态,而且只能从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,任何其他操作都无法改变这个状态。
Promise对象也是一个构造函数,可以用来生成Promise实例,它的语法是:
const promise = new Promise(function(resolve, reject) {
// /* executor */
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
Promise构造函数接受一个函数(executor)作为参数,它会在Promise构造函数执行时被立即调用,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。
promise.then(function(value) {
// success
}, function(error) {
// failure
});
Promise.prototype.catch方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时的回调函数。
promise.catch(function(error){
console.log(error)
});
因为 Promise.prototype.then 和 Promise.prototype.catch方法返回promise 对象, 所以它们可以被链式调用。

doSomething() // return promise .then(result => doSomethingElse(value)) .then(newResult => doThirdThing(newResult)) .then(finalResult => console.log(`Got the final result: ${finalResult}`)) .catch(failureCallback);
为了避免意外,即使是一个已经变成 resolve 状态的 Promise,传递给 then 的函数也总是会被异步调用:
Promise.resolve().then(() => console.log(2)); console.log(1); // 1, 2
传递到then中的函数被置入了一个微任务队列,而不是立即执行,这意味着它是在JavaScript事件队列的所有运行时结束了,事件队列被清空之后才开始执行:
const wait = ms => new Promise(resolve => setTimeout(resolve, ms)); wait().then(() => console.log(4)); Promise.resolve().then(() => console.log(2)).then(() => console.log(3)); console.log(1); // 1, 2, 3, 4
返回一个 Promise 实例,在参数内所有的 promise 都“完成(resolved)”或参数中不包含 promise 时回调完成(resolve);如果参数中 promise 有一个失败(rejected),此实例回调失败(reject),失败原因的是第一个失败 promise 的结果。
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then(function(values) {
console.log(values);
});
// expected output: Array [3, 42, "foo"]
返回一个 Promise,它将与参数中第一个传递的 promise 相同的完成方式被完成。它可以是完成( resolves),也可以是失败(rejects),这要取决于第一个完成的方式是两个中的哪个。 如果传的迭代是空的,则返回的 promise 将永远等待。
var p1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 500, "one");
});
var p2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, "two");
});
Promise.race([p1, p2]).then(function(value) {
console.log(value); // "two"
// 两个都完成,但 p2 更快
});
返回一个以给定值解析后的Promise 对象。
var original = Promise.resolve('我在第二行'); var cast = Promise.resolve(original); cast.then(function(value) { console.log('value: ' + value); }); console.log('original === cast ? ' + (original === cast)); /* * 打印顺序如下,这里有一个同步异步先后执行的区别 * original === cast ? true * value: 我在第二行 */
返回一个带有拒绝原因reason参数的Promise对象。
Promise.reject("Testing static reject").then(function(reason) {
// 未被调用
}, function(reason) {
console.log(reason); // "Testing static reject"
});
Promise.reject(new Error("fail")).then(function(result) {
// 未被调用
}, function(error) {
console.log(error); // stacktrace
});
返回一个Promise,在promise执行结束时,无论结果是fulfilled或者是rejected,在执行then()和catch()后,都会执行finally指定的回调函数。
由于无法知道promise的最终状态,所以finally的回调函数中不接收任何参数,它仅用于无论最终结果如何都要执行的情况。
let isLoading = true;
fetch(myRequest).then(function(response) {
var contentType = response.headers.get("content-type");
if(contentType && contentType.includes("application/json")) {
return response.json();
}
throw new TypeError("Oops, we haven't got JSON!");
})
.then(function(json) { /* process your JSON further */ })
.catch(function(error) { console.log(error); })
.finally(function() { isLoading = false; });
可以用async声明一个异步函数,这个函数会返回一个promise,使用awiat可以让语法更加同步。当这个 async 函数返回一个值时,Promise 的 resolve 方法会负责传递这个值;当 async 函数抛出异常时,Promise 的 reject 方法也会传递这个异常值。
await 表达式,会使 async 函数暂停执行,等待 Promise 的结果出来,然后恢复async函数的执行并返回解析值(resolved)。await只能接一个promise。
注意, await 关键字仅仅在 async function中有效。如果在 async function函数体外使用 await ,你只会得到一个语法错误(SyntaxError)。
async function foo() {
try {
let result = await doSomething();
let newResult = await doSomethingElse(result);
let finalResult = await doThirdThing(newResult);
console.log(`Got the final result: ${finalResult}`);
} catch(error) {
failureCallback(error);
}
}
使用try catch 也因为它相比promise.then更像同步代码.这是发明这个语法的初衷