出处: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()//
} }).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。

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

  1. C# 同步 异步 回调 状态机 async await Demo

    源码 https://gitee.com/s0611163/AsyncAwaitDemo 为什么会研究这个? 我们项目的客户端和服务端通信用的是WCF,我就想,能不能用异步的方式调用WCF服务呢?或者 ...

  2. 前端笔记之JavaScript(九)定时器&JSON&同步异步/回调函数&函数节流&call/apply

    一.快捷位置和尺寸属性 DOM已经提供给我们计算后的样式,但是还是觉得不方便,因为计算后的样式属性值都是字符串类型. 不能直接参与运算. 所以DOM又提供了一些API:得到的就是number类型的数据 ...

  3. js 同步 异步 宏任务 微任务 文章分享

    分享一篇 写的很好的 宏任务 微任务  同步异步的文章 文章原地址: https://juejin.im/post/59e85eebf265da430d571f89 这一次,彻底弄懂 JavaScri ...

  4. 【java回调】同步/异步回调机制的原理和使用方法

    回调(callback)在我们做工程过程中经常会使用到,今天想整理一下回调的原理和使用方法. 回调的原理可以简单理解为:A发送消息给B,B处理完后告诉A处理结果.再简单点就是A调用B,B调用A. 那么 ...

  5. C#--委托的同步,异步,回调函数

    原文地址 同步调用 委托的Invoke方法用来进行同步调用.同步调用也可以叫阻塞调用,它将阻塞当前线程,然后执行调用,调用完毕后再继续向下进行. using System; using System. ...

  6. 十四、JS同步异步知识点,重点(Node.js-fs模块补充篇)

    (本片文章如果你能耐着性子看我,保证会对同步和异步有一个非常深刻的理解) JavaScript是单线程执行,所谓的单线程呢就是指如果有多个任务就必须去排队,前面任务执行完成后,后面任务再执行.因为Ja ...

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

    ####################总结######################## 管道:是进程间通信的第二种方式,但是不推荐使用,因为管道会导致数据不安全的情况出现 事件:当我运行主进程的 ...

  8. js同步 异步 运行机制

    需要知道的那些事: 1.JS是单线程的(为什么?因为能提高效率.作为浏览器脚本语言,js的主要用途是与用户互动,操作DOM.而这也就决定它只能为单线程,否则会带来很复杂的同步问题),也就是说无法同时执 ...

  9. JS的异步回调函数

    hi :)几日不见,趁着周末和父母在广州走走逛逛,游山玩水,放松身心,第一天上班就被一个问题难住了,不废话,以下是关于JS函数回调方面的知识,今天的查阅看的也是一知半解,摘录下来日后慢慢琢磨! js中 ...

随机推荐

  1. chartControl ViewType.Bar 用法测试

    使用方法 一. Datatable : chartControl1.Series.Clear(); DataTable dt = new DataTable(); dt.Columns.Add(&qu ...

  2. leaflet计算多边形面积

    上一篇介绍了使用leaflet绘制圆形,那如何计算圆形的面积呢? 1.使用数学公式计算,绘制好圆形后,获取中心点以及半径即可 2.使用第三方工具计算,如turf.js. 这里turf的area方法入参 ...

  3. Android项目实战(四十七):轮播图效果Viewpager

    简易.常用的轮播图效果ViewPager ,老技术了,记一笔留着以后ctrl C + ctrl V    需求如下: 不定张个数的ImagView轮播,右下角显示轮播点图标,每隔固定时间切换下一张,最 ...

  4. WPF:自定义Metro样式文件夹选择对话框FolderBrowserDialog

    1.前言 WPF并没有文件选择对话框,要用也就只有使用Winform版的控件.至今我也没有寻找到一个WPF版本的文件选择对话框. 可能是我眼浊,如果各位知道有功能比较健全的WPF版文件选择对话框.文件 ...

  5. (其他)window10分盘

    由于thinkpad的一个c盘大概是一个t左右,所以我们先分一下盘.   首先找到计算机管理,然后找磁盘管理,右击比较大的磁盘,压缩卷,大概就压缩一半吧,然后新建简单卷,一直下一步,紧接着就完成了. ...

  6. 编程经验点滴----巧妙解决 Oracle NClob 读写问题

    最近一个新项目中,尝试在 Oracle 数据库中使用 NCLOB 来保存大的 xml 字符串. 在代码自动生成工具(通过 JDBC 驱动程序,读数据库表结构,自动生成对应的 java 代码,包含增加. ...

  7. python之restful api(flask)获取数据

    需要用到谷歌浏览器的扩展程序 Advanced Rest Client进行模拟请求 1.直接上代码 from flask import Flask from flask import request ...

  8. Linux中对逻辑卷的移除

    移除前先df -mT 看一下:(在上一篇的基础上:Linux中对逻辑卷进行扩容) 1.取消挂载同时删除/etc/fstab下的记录 取消挂载 umount /dev/zhi/lv-zhi 删除记录 v ...

  9. [20181225]12CR2 SQL Plan Directives.txt

    [20181225]12CR2 SQL Plan Directives.txt --//12C引入SQL PLAN Directives.12cR1版本会造成大量的动态取样,影响性能.许多人把OPTI ...

  10. html常见标签和属性

    主体 body中常见属性 属性 表格 列表 表单 其他 input字段属性 form字段属性