随着node在前端的地位越来越高。大量的求职者总会随笔一下:
熟悉Node.js开发
ok。到这里,面试官便发问了:
- 什么是promise?
- promise是如何捕获异常的 ...
为什么promise是必不可少的呢?
回答这个问题前,我不知道大家是否有疑问?
Node是前端语言还是后端语言?
为什么会有这种疑问呢?
其实因为大多数的开发者其实或多或少的总会有node打交道,心底上认为这是一种前端语言
其实区分node是否是前端语言,很简单,只要记住这点就可以了
你主要用node去干什么?
你用node去构建工程,那node就是前端语言
你用node去做后台开发,那node就是后端语言
一般而言,node更像后端语言,无论是写法,还是思维方式更接近于后端。而此时就突出Promise的重要性了?
下面让我们去总结一下promise的几个知识点吧,让所有的求职者求职必过,心有所属。
promise对象及实例
1、 什么是promise
Promise是一个对象,从它可以获取异步操作的结果。Promise提供统一的API,各种异步操作都可以用相同的方式进行处理
2、Promise对象的特点是什么
Promise对象有两个特点。
(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果
3、Promise实例
const promsie = new Promise((resolve, reject)=>{
// code...
if (/* 异步操作成功 */){
resolve(value)
} else {
reject(value)
}
})
promise.then(function (value) {
// success
}, function (error) {
// failure
});
4、手写一个promise实例
function timeout(ms) {
return new Promise((resove, reject)=>{
console.log("ok")
setTimeout(() => {
resove('done')
}, ms);
})
}
timeout(5000)
.then((value)=>{
console.log(value)
})
.catch((error)=>{
console.log(error)
})
原型和原型链
1.原型
Promise 实例具有then方法,也就是说,then方法是定义在原型对象Promise.prototype上的
2.原型链
then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。
getJSON("/post/1.json").then(function(post) {
return getJSON(post.commentURL);
}).then(function (comments) {
console.log("resolved: ", comments);
}, function (err){
console.log("rejected: ", err);
});
promise的API
- promise.prototype.then()
- promise.prototype.catch()
- promise.prototype.finally()
- promise.all()
- promise.race()
- promise.allSettled()
- promise.any()
- promise.resolve()
- promise.reject()
async
什么是async
async函数返回一个 Promise 对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。
async例子
function timeout(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
async function asyncPrint(value, ms) {
await timeout(ms);
console.log(value);
}
asyncPrint('hello world', 50);
由于async函数返回的是 Promise 对象,可以作为await命令的参数。所以,上面的例子也可以写成下面的形式。
async function timeout(ms) {
await new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
async function asyncPrint(value, ms) {
await timeout(ms);
console.log(value);
}
asyncPrint('hello world', 50);
async的实现原理
async 函数的实现原理,就是将 Generator 函数和自动执行器,包装在一个函数里。
async function fn(args) {
// ...
}
// 等同于
function fn(args) {
return spawn(function* () {
// ...
});
}
function spawn(genF) {
return new Promise(function(resolve, reject) {
const gen = genF();
function step(nextF) {
let next;
try {
next = nextF();
} catch(e) {
return reject(e);
}
if(next.done) {
return resolve(next.value);
}
Promise.resolve(next.value).then(function(v) {
step(function() { return gen.next(v); });
}, function(e) {
step(function() { return gen.throw(e); });
});
}
step(function() { return gen.next(undefined); });
});
}
async与promise代码比较
Promise 的写法如下。
function logInOrder(urls) {
// 远程读取所有URL
const textPromises = urls.map(url => {
return fetch(url).then(response => response.text());
});
// 按次序输出
textPromises.reduce((chain, textPromise) => {
return chain.then(() => textPromise)
.then(text => console.log(text));
}, Promise.resolve());
}
aysnc 的写法如下
async function logInOrder(urls) {
// 并发读取远程URL
const textPromises = urls.map(async url => {
const response = await fetch(url);
return response.text();
});
// 按次序输出
for (const textPromise of textPromises) {
console.log(await textPromise);
}
}
Promise的这种写法不太直观,可读性比较差
总结
Promise是一个不错异步操作解决方案,他解决了传统的通过回调和事件来解决异步操作的诸多问题,如“竞争”,回调信任度低的问题。
最后祝愿各位求职者心想事成,虎虎生威!