promise,async await ,generator的区别和nextTick , setImmedate的关系

promise anyse generator区别和nextTick setImmediate 的关系

promise

1.什么是promise

所谓 Promise,就是一个对象,用来传递异步操作的消息。它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供统一的 API,可供进一步处理。

2.promise的作用

Promise的出现主要是解决回调地狱的问题,比如你需要结果需要请求很多个接口,这些接口的参数需要另外那个的接口返回的数据作为依赖,这样就需要我们一层嵌套一层,但是有了Promise 我们就无需嵌套

3.promise的基本api

  Promise.resolve()//表示成功Promise.reject()//表示失败Promise.prototype.then()//成功时要干嘛Promise.prototype.catch()//失败时要干嘛Promise.all() // 所有的完成Promise.all([p1,p2,p3])

4.封装ajax

var p = new Promise(function(resolve, reject) { 
   var xhr = new XMLHttpRequest(); 
   xhr.open('get', 'url'); 
   xhr.send(); xhr.onreadystatechange = function() {
   if (xhr.readyState == 4 && xhr.status == 200) { 
   resolve(xhr.responseText); } 
   setInterval(function() { 
   reject(new Error('连接超时')); }, 2000) } });
   p.then(function(data) { console.log(data) }).catch(function(err) { if (err) throw err; }).finally(function() { console.log('asdf') })

5.Promise.all方法

let p1 = new Promise((resolve, reject) => { resolve('成功了') })
let p2 = new Promise((resolve, reject) => { resolve('success') }) 
let p3 = Promse.reject('失败') 
Promise.all([p1, p2]).then((result) => { console.log(result) //['成功了', 'success'] })
.catch((error) => { console.log(error) }) Promise.all([p1,p3,p2])
.then((result) => { //全部成功了才执行 console.log(result) })
.catch((error) => { //有一个失败了就是失败 console.log(error) })

6.Promise.race方法

let p1 = new Promise((resolve, reject) => { setTimeout(() => { resolve('success') },1000) }) 
let p2 = new Promise((resolve, reject) => { setTimeout(() => { reject('failed') }, 500) }) Promise.race([p1, p2]).then((result) => { console.log(result) }).catch((error) => { console.log(error) // 打开的是 'failed' })

gengerator 函数

1.

接触过Ajax请求的会遇到过异步调用的问题,为了保证调用顺序的正确性,一般我们会在回调函数中调用,也有用到一些新的解决方案如Promise相关的技术。在异步编程中,还有一种常用的解决方案,它就是Generator生成器函数。顾名思义,它是一个生成器,它也是一个状态机,内部拥有值及相关的状态,生成器返回一个迭代器Iterator对象,我们可以通过这个迭代器,手动地遍历相关的值、状态,保证正确的执行顺序

1.5.

es6 提供的 generator函数

  1. 在function关键字后加一个* , 那么这个函数就称之为generator函数
  2. 函数体有关键字 yield , 后面跟每一个任务 , 也可以有return关键字, 保留一个数据
  3. 通过next函数调用, 几个调用, 就是几个人任务执行

2.

Generator的声明方式类似一般的函数声明,只是多了个 * 号,并且一般可以在函数内看到yield关键字

  function* showWords() {
    yield 'one'; //yield关键字后面跟的是任务
    yield 'two';
    return 'three'; //return表示之后的yield语句将不再执行
            } 
    var show = showWords();
    show.next() // {done: false, value: "one"}
    show.next() // {done: false, value: "two"} 
    show.next() // {done: true, value: "three"}
    show.next() // {done: true, value: undefined}

4.yield 和yield* 的区别

yield后面接的是任务,如果任务只是个简单的数据,就可以直接输出,若是yield后面的任务是一个对象或者函数的话yield关键字就不好用了,函数体会停留在这里,这时候就要在yield后面加个 * 号,yield*表示自动遍历对象

5.generator函数通过.next()方法调用,写几个.next()就执行几个任务

async await

1.async 函数是什么?一句话,它就是 Generator 函数的语法糖。

async await函数语法与generator函数相似,只要把 * 号换成async,然后把yield换成await就可以

2.async await函数与generator函数的不同

1.内置执行器

Generator 函数的执行必须靠执行器,所以才有了co模块,而async函数自带执行器。也就是说,async函数的执行,与普通函数一模一样,只要一行。

2.更好的语义。

async和await,比起星号和yield,语义更清楚了。async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。

3.更广的适用性

co模块约定,yield命令后面只能是 Thunk 函数或 Promise 对象,而async函数的await命令后面,可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时会自动转成立即 resolved 的 Promise 对象)。

4.返回值是 Promise。

async函数的返回值是 Promise 对象,这比 Generator 函数的返回值是 Iterator 对象方便多了。你可以用then方法指定下一步的操作。进一步说,async函数完全可以看作多个异步操作,包装成的一个 Promise 对象,而await命令就是内部then命令的语法糖。

nodejs中的Process.nextTick() 和 setImmediade()的区别

1.轮询

nodejs中是事件驱动的,有一个循环线程一直从事件队列中取任务执行或者I/O的操作转给后台线程池来操作,把这个循环线程的每次执行的过程算是一次轮询.

2.setImmediate()的使用

即时计时器立即执行工作,它是在事件轮询之后执行,为了防止轮询阻塞,每次只会调用一个。

3.Process.nextTick()的使用

它和setImmediate()执行的顺序不一样,它是在事件轮询之前执行,为了防止I/O饥饿,所以有一个默认process.maxTickDepth=1000来限制事件队列的每次循环可执行的nextTick()事件的数目。

4.总结

process.nextTick()属于idle观察者,setImmediate()属于check观察者.在每一轮循环检查中,idle观察者先于I/O观察者,I/O观察者先于check观察者.在具体实现上,process.nextTick()的回调函数保存在一个数组中,
setImmediate()的结果则是保存在链表中.
在行为上,process.nextTick()在每轮循环中会将数组中的回调函数全部执行完.
而setImmediate()在每轮循环中执行链表中的一个回调函数.

案例

//加入2个nextTick()的回调函数
process.nextTick(function(){
    console.log("nextTick延迟执行A");
});
process.nextTick(function(){
    console.log("nextTick延迟执行B");
    setImmediate(function(){
        console.log("setImmediate延迟执行C");
    });
    process.nextTick(function(){
        console.log("nextTick延迟执行D");
    });
});
//加入两个setImmediate()回调函数
setImmediate(function(){
    console.log("setImmediate延迟执行E");
    process.nextTick(function(){
        console.log("强势插入F");
    });
    setImmediate(function(){
        console.log("setImmediate延迟执行G");
    });
});
setImmediate(function(){
    console.log("setImmediate延迟执行H");
    process.nextTick(function(){
        console.log("强势插入I");
    });
    process.nextTick(function(){
        console.log("强势插入J");
    });
    setImmediate(function(){
        console.log("setImmediate延迟执行K");
    });
});
console.log("正常执行L");
结果
正常执行L
nextTick延迟执行A
nextTick延迟执行B
nextTick延迟执行D
setImmediate延迟执行E
setImmediate延迟执行H
setImmediate延迟执行C
强势插入F
强势插入I
强势插入J
setImmediate延迟执行G
setImmediate延迟执行K

Process finished with exit code 0

猜你喜欢

转载自blog.csdn.net/zhangyuea/article/details/89320902
今日推荐