js同步-异步-回调

出处:https://blog.csdn.net/u010297791/article/details/71158212
(1)上面主要讲了同步和回调执行顺序的问题,接着我就举一个包含同步、异步、回调的例子。html

    let a = new Promise(//声明了一个Promise回调函数,可以使用then
  function(resolve, reject) {
    console.log(1)
    setTimeout(() => console.log(2), 0)
    console.log(3)
    console.log(4)
    resolve(true)
  }
)
a.then(v => {
  console.log(8)
})
 
let b = new Promise(
  function() {
    console.log(5)
    setTimeout(() => console.log(6), 0)
  }
)
 
console.log(7)


     在看正确结果以前,我先进行分析题目(访问顺序:同步 => 异步 => 回调):
    1)看同步代码:a变量是一个Promise,Promise的异步指的是他的then()和catch()方法,Promise自己仍是同步的,因此这里先执行a变量内部的Promise同步代码。(同步优先)
    console.log(1)
    setTimeout(() => console.log(2), 0) //回调
    console.log(3)
    console.log(4)
    2)Promise内部有4个console,第二个是一个setTimeout回调(回调垫底(意思就是你先让它等着),因此暂时不输出)。因此这里先输出1,3,4,回调的方法丢到消息队列中排队等着。
    3)接着执行resolve(true),进入then(),then是异步,下面还有同步没执行完呢,因此then也去消息队列排队等候。(异步靠边)
    4)b变量也是一个Promise,和a同样,一样是同步的,执行内部的同步代码,输出5,setTimeout是回调,去消息队列排队等候,这里输出5。
    5)最下面同步输出7。
    6)如今同步的代码执行完了,JavaScript就跑去消息队列呼叫异步的代码:异步,出来执行了。这里只有一个异步then,因此输出8。
   7)此时,异步也over,轮到回调函数:回调,出来执行了。这里有2个回调在排队,他们的时间都设置为0,因此不受时间影响,只跟排队前后顺序有关。则先输出a里面的回调2,最后输出b里面的回调6。
   8)最终输出结果就是:一、三、四、五、七、八、二、6。

(2)分析下面这个例子的执行顺序promise

var Pro = function () {
   //返回一个Promise对象
   return new Promise(function (resolve, reject) {
    //模拟接口调用
    setTimeout(function () {//1,回调等待,同步执行
     resolve(true);//4,而后进入then函数
    }, 1000);
   })
  };
  var Pro2 = function () {
   //返回一个Promise对象
   return new Promise(function (resolve, reject) {
    //模拟接口调用
    setTimeout(function () {//2,回调等待
     resolve(‘Pro2成功执行’);//9,访问另外一个then
    }, 1000);
   })
  };
  
  Pro().then(function(data){//3异步等待
   var val = data;//5,resolve传入的data是true
   console.log(val)//6,因此先输出true
   if (val) {
    console.log(1111)//7,再输出1111
    return Pro2()//8
   }
   
  }).then(function(data1){//8异步等待
   console.log(data1)//10,输出Pro2成功执行
  })

输出:
异步


(3)async/await(代替了promise)
能够先看http://www.ruanyifeng.com/blog/2015/05/async.html
async 函数返回一个 Promise 对象,可使用 then 方法添加回调函数。当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操做完成,再接着执行函数体内后面的语句。
下面是一个例子。
//getStockSymbol(name)和getStockPrice(symbol)都是异步函数,这样才能使用
//await进行声明,当两个异步函数调用完后,返回一个Promise对象,其值为
//stockPrice
async function getStockPriceByName(name) {
  var symbol = await getStockSymbol(name);
  var stockPrice = await getStockPrice(symbol);
  return stockPrice;
}

//而后就可使用then函数来获得返回的值result == stockPrice
getStockPriceByName('goog').then(function (result){
  console.log(result);
});


//若是在函数function (result){}中运行了比较复杂的语句最好是加上catch来捕获err,如:
getStockPriceByName('goog').then(function (result){
  console.log(result);
}).catch((err) =>{
    console.log(err);
        });

上面代码是一个获取股票报价的函数,函数前面的async关键字,代表该函数内部有异步操做。调用该函数时,会当即返回一个Promise对象。

这个东西的使用手法就是:
首先你先写一个return new Promise的回调function,这个function就不用声明为async,而后就能够在另外一个声明为async的函数中使用这个回调function ,使用时前面代表await,await等待的虽然是promise对象,但没必要写.then(..),直接能够获得返回值;另外一个使用的办法则是直接使用then函数回调,而后用catch函数捕捉错误。


在async函数中若是有await的声明,只能说后面要进行的操做是异步操做来得到返回值的,若是前后,如:
   async

let c = await count();

    函数

let l = await list();
return {count:c,list:l};
只是说明二者只是写的时候好像有了个先后关系,可是他们不是同步的,而是异步的,因此他们能够同时进行运算,而后等待二者结果都出来了之后进行拼装罢了


当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操做完成,再接着执行函数体内后面的语句

我是这么理解promise和async/await二者的使用的,我以为当要使用过多异步的时候,使用async/await更好,好比:测试

var id;
create(user1,’0x0000002’,10,10).then((result) => {
    if(result){
        console.log(result);
        return owned(user1);  //获得user1建立的tokenID
    }
}).then((result) => {
    if(result){
        id = result;
        console.log('num is :' + result);
        return sell(result);  //卖掉该token
    }   
}).then((result) => {
    if(result){
        console.log(result);
        return buy(user2,40,id);  
    }       
}).catch((err) =>{
    console.log(err);
});


当咱们想要对一系列回调函数进行有序测试时,若是使用的是then,那么最后看起来真的很繁杂;可是若是使用的是async/await,那么就能够变成:spa

var test = async() => {
    try{
        await create(user1,’0x0000002’,10,10);
        var id = await owned(user1);
        await sell(id);
        await buy(user2,40,id);
    }catch(err){
        console.log(err);
    }
}

光是看起来就好不少了

注意:当一个函数被声明为async时,说明它是异步的,说明它的返回值是promise类型的,调用函数后后面能够用then进行返回值的调用,而不是说它的函数中必定要出现await。


.net