js同步-异步-回调

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

    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)最终输出结果就是:1、3、4、5、7、8、2、6。

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

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的声明,只能说后面要进行的操作是异步操作来获得返回值的,如果先后,如:?

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,那么就可以变成:

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。

原文地址:https://www.cnblogs.com/wanghui-garcia/p/9507142.html

时间: 2024-08-11 07:41:53

js同步-异步-回调的相关文章

同步异步 + 回调函数

重点记忆 异步回调函数 如果进程池+回调: 回调函数由主进程去执行. 如果线程池+回调: 回到函数由空闲的线程去执行.(比如有4个线程,10个任务,第一轮完成4个任务,交由主线程处理结果,第二轮同样如此,但是第三轮将会空闲出2个子进程,则这2个子进程将会和主进程一同处理结果,以此类推,当所有的任务完成时,所有的子进程和主进程一起处理结果,增加效率) 回调函数不管有没有返回数据,返回值都是None,回调函数内部加函数名是调用此函数,obj隐形传参 1.概念 1. 从执行的角度 阻塞: 程序运行时,

协程,事件,队列,同步,异步,回调函数

协程 什么是协成?单个线程并发的处理多个任务,程序控制协成的切换+保持状态,协成的切换速度非常快,蒙蔽了操作系统的眼睛,让操作系统认为CPU一直在运行 进程或线程都是由操作系统控制CPU来回切换,遇到阻塞就切换执行其他任务,协成是程序控制的,霸占CPU执行任务,会在操作系统控制CPU之前来回切换,操作系统就认为CPU一直在运作 协程的优点: 1.开销小 2.运行速度快 3.协程会长期霸占CPU只执行我程序里的所有任务 协程的缺点: 1.协程属于微并发,处理任务不易过多 2.协程的本质是单线程,无

【Javascript】Js同步异步以及回调函数

一.前言 今天查看了requireJs方面的知识,看着看着就看到了JS中同步与异步操作的知识点,经过查阅了很多的资料,基本了解了JS的同步与异步的操作,其中涉及到的知识点如下: 什么时同步和异步? JS的是基于事件驱动的单线程语言,为啥会有异步操作这种多线程的操作??? 浏览器线程,浏览器内核线程间的合作? JS的异步操作都有哪些?它是如何工作的? 二.js单线程 JS的单线程 单线程的含义是js只能在一个线程上运行,也就是说,同一时间只能做一件事情,其他的任务则会放在任务队列里面排队等等js线

js同步异步执行顺序setTimeOut面试题分析

<script> for(var i=0;i<2;i++){ setTimeout(function(){ console.log(i); },0); } </script> // 结果:2,2 打印两个2而不是0,1,跟js执行顺序有关系. 所有的任务分为两种,一种是同步任务,一种是异步任务.同步任务是指在主线程上排队的任务.异步任务是指不进入主线程.而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异

js的异步回调事件

转载的: 转自阮一峰的博客:http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html 一.回调函数 这是异步编程最基本的方法. 假定有两个函数f1和f2,后者等待前者的执行结果. f1(); f2(); 如果f1是一个很耗时的任务,可以考虑改写f1,把f2写成f1的回调函数. function f1(callback){ setTimeout(function () { // f1的任务代码 callb

同步异步,回调

聊聊同步.异步和回调 给产品经理讲技术 ? 2016-01-04 ? 深氪 有一天,你找到公司刚来的程序员小T,跟他说:我们要加个需求,你放下手里的事情优先支持,我会一直等你做完再离开.小T微笑着答应了,眼角却滑过一丝不易觉察的杀意. 本文来自微信公众号"给产品经理讲技术"(pm_teacher),欢迎大家关注. 有一天,你找到公司刚来的程序员小T,跟他说:"我们要加个需求,你放下手里的事情优先支持,我会一直等你做完再离开".小T微笑着答应了,眼角却滑过一丝不易觉察

python 管道 事件 信号量 进程池(map/同步/异步)回调函数

####################总结######################## 管道:是进程间通信的第二种方式,但是不推荐使用,因为管道会导致数据不安全的情况出现 事件:当我运行主进程的时候 需要子执行某个进程后 需要的返回值时 可以使用 信号量:互斥锁同时只允许一个线程更改数据,而信号量Semaphore是同时允许一定数量的线程更改数据 . 内部维护了一个计数器,acquire-1,release+1,为0的时候,其他的进程都要在acquire之前等待 进程池:  进程的创建和销

Js同步异步机制

JavaScript引擎是单线程的,强制所有的异步事件排队等待执行 setTimeout 和 setInterval 在执行异步代码的时候有着根本的不同 如果一个计时器被阻塞而不能立即执行,它将延迟执行直到下一次可能执行的时间点才被执行(比期望的时间间隔要长些) 如果setInterval回调函数的执行时间将足够长(比指定的时间间隔长),它们将连续执行并且彼此之间没有时间间隔 animate因为内部利用的实际是setInterval $(function(){ for(var i=0;i<10;

node.js的作用、回调、同步异步代码、事件循环

http://www.nodeclass.com/articles/39274 一.node.js的作用 I/O的意义,(I/O是输入/输出的简写,如:键盘敲入文本,输入,屏幕上看到文本显示输出.鼠标移动,在屏幕上看到鼠标的移动.终端的输入,和看到的输出.等等) node.js想解决的问题,(处理输入,输入,高并发 .如 在线游戏中可能会有上百万个游戏者,则有上百万的输入等等)(node.js适合的范畴:当应用程序需要在网络上发送和接收数据时Node.js最为适合.这可能是第三方的API,联网设