Promise详解
作者:互联网
简述
promise是ES6提供的类,目的是更加优雅地书写复杂的异步任务,同时也能避免回调金字塔问题的出现。
promise并不是把异步转化为同步了,Promise只不过是一种更良好的编程风格。
构造promise
传递给 new Promise
的函数被称为 executor。当 new Promise
被创建,executor会自动运行。
new Promise(function (resolve, reject) { // executor });
它的参数 resolve
和 reject
是由 JavaScript 自身提供的回调。
当executor获得了结果,就应当执行resolve或reject之一
resolve(value)
—— 如果任务成功完成并带有结果value
reject(error)
—— 如果出现了 error,error
即为 error 对象
promise的三钟状态
promise有两个重要的属性,state和result,promise一共有三种状态
promise刚被构造的时候,state是pending,result是undefined,通过resolve和reject的调用可以让promise转向另两种状态。
then和catch
then和catch可以消费promise中excutor产生的结果
promise.then( function(result) { /* handle a successful result */ }, function(error) { /* handle an error */ } );
第一个函数会在 promise resolved 且接收到结果后执行,第二个函数会在promise rejected 且接收到 error 信息后执行。
当然你如果只关心成功的状态则可以只传第一个函数
如果只对error感兴趣可以第一个函数传null,也可以使用catch
let promise = new Promise((resolve, reject) => { setTimeout(() => reject(new Error("Whoops!")), 1000); }); // .catch(f) 与 promise.then(null, f) 一样 promise.catch(alert); // 1 秒后显示 "Error: Whoops!"
finally
finally类似java中try...catch...finally的一样,finally的功能是设置一个处理程序在前面的操作完成后,执行清理/终结。
在finally中我们是不知道promise是否成功,我们的目的只是执行“常规”的完成程序
finally处理程序也不应该返回任何内容。如果它返回了,返回的值会默认被忽略。
处理回调金字塔
对于想分三次输出字符串,第一次间隔 1 秒,第二次间隔 4 秒,第三次间隔 3 秒,这个需求
多次调用异步函数是这样子的
setTimeout(function () { console.log("First"); setTimeout(function () { console.log("Second"); setTimeout(function () { console.log("Third"); }, 3000); }, 4000); }, 1000);
可以看到异步操作的步骤链越长,就会有越多函数的嵌套,代码的可读性就会降低
如果用promise来实现这个需求,我们可以把需求的核心写成一个promise函数
function print(delay, message) { return new Promise(function (resolve, reject) { setTimeout(function () { console.log(message); resolve(); }, delay); }); }
这个函数返回一个promise实例对象,我们就可以通过使用then链进行异步操作
print(1000, "First").then(function () { return print(4000, "Second"); }).then(function () { print(3000, "Third"); });
async/await
async/await 是以更舒适的方式使用 promise 的一种特殊语法,同时它也非常易于理解和使用
async用于标识一个函数会返回一个promise,它原本的返回值会包含在promise的resolved里
async function f() { return 1; } f().then(alert); // 1
await关键字只能在async标识的函数内使用
语法:
let value = await promise;
关键字 await
让 JavaScript 引擎等待直到 promise 完成(settle)并返回结果。
async function f() { let promise = new Promise((resolve, reject) => { setTimeout(() => resolve("done!"), 1000) }); let result = await promise; // 等待,直到 promise resolve (*) alert(result); // "done!" } f();
这个函数在执行的时候,“暂停”在了 (*)
那一行,并在 promise settle 时,拿到 result
作为结果继续往下执行。所以上面这段代码在一秒后显示 “done!”。
References
https://www.runoob.com/js/js-promise.html
https://zh.javascript.info/promise-basics
https://zh.javascript.info/async-await
标签:function,resolve,error,详解,promise,reject,Promise 来源: https://www.cnblogs.com/CNLayton/p/16556947.html