Javascript的异步函数和Promise对象你了解吗

目录
  • 1、JS中的异步
    • 1.1同步
    • 1.2异步
    • 1.3回调函数解决异步问题
    • 1.4回调地狱
  • 2、Promise对象
    • 2.1Promise的基本使用
    • 2.2async和await
  • 总结

1、JS中的异步

1.1 同步

一般情况下,js的代码都是自上而下顺序运行的。例如:

let res = '';
res = '获取到的结果!';
console.log(res);

结果:

很容易理解,我给res赋了新值,然后输出res。这就是js的同步执行,这里的同步,并不是一起执行的意思,而是在一个线程里顺序执行的意思。因为JavaScript是单线程,所以所有程序都应该在一个线程里运行。

1.2 异步

但是有的时候,我们获取res的值是需要一点时间的,例如使用ajax向服务器发起请求,服务器响应以后返回结果,我们再将结果赋值给res。

这里使用setTimeout函数模拟数据请求,setTimeout也是一个异步函数。

let res = '';
setTimeout(()=>{
    res = '获取到的结果!';
    console.log('获取到结果了!',res);
},3000);
console.log('res',res);

可以看到,没有立刻获取到结果,而是3s后才获取到结果。

为什么会这样呢?
由于获取res它是一个异步操作,所以它会被分为两部分来执行,先调用setTimeout方法,然后把要执行的函数放到一个队列中。代码继续往下执行,当把所有的代码都执行完后,放到队列中的函数才会被执行。因为js的单线程机制,不允许它花费时间去等待异步函数的结果。

1.3 回调函数解决异步问题

既然异步函数的结果会再最后获取,那么我们就可以给异步函数中加一个回调函数,来处理获取到的数据。

let res = '';
setTimeout(()=>{
    res = '获取到的结果!';
    callback();
},3000);
function callback(){
    console.log('获取到结果了!',res);
    console.log('处理结果!');
}
console.log('res', res);

现在console.log('res', res);仍然没有获取到res,但是我们已经不需要它了,我们获取res的就是为了处理它,而使用callback函数就可以达到目的了!

1.4 回调地狱

1.3了解了可以通过调用函数解决无法获取结果的问题,但是它仍然是存在缺点的,如果只获取一次结果,那还好。但是如果我们在获取结果之后,还需要利用获取的结果再进行异步操作,那么又需要嵌套一层,又需要一次异步操作,再嵌套一层……

setTimeout(function(){
    console.log("first");
    setTimeout(function(){
        console.log("second");
        setTimeout(function(){
            console.log("third");
            setTimeout(function(){
                console.log("fourth");
            },2000);
        },2000);
    },2000);
},2000);

虽然上述代码会按照我们预期的方向运行,但是多层的嵌套让代码阅读和维护起来十分的困难。

2、Promise对象

2.1 Promise的基本使用

为了解决异步中的回调地狱问题,ES6引入了Promise对象,使得我们可以十分优雅地进行异步操作。
从语法上来说,Promise是一个对象,从它可以获取异步操作的消息。

let timeout = function(time){
    return new Promise(function(resolve,reject){
        setTimeout(function(){
            resolve();
        },time);
    });
}
console.log("开始运行!");
timeout(2000).then(function(){
    console.log("first");
    return timeout(2000);
}).then(function(){
    console.log("second");
    return timeout(2000);
}).then(function(){
    console.log("third");
    return timeout(2000);
}).then(function(){
    console.log("fourth");
    return timeout(2000);
});

这样就解决了上述的回调地狱的问题。并且then也很容易理解,就是上一个异步函数执行完成后,接着要进行的操作。

同时Promise对象也可以通过resolve和reject传递参数:

let res = null;
let timeout = function(time){
    return new Promise(function(resolve,reject){
        setTimeout(function(){
            res = false;
            if(res){
                resolve('res为true');
            }else{
                reject('res为false');
            }
        },time);
    });
}
timeout().then((res)=>{
    console.log(res);
}).catch((error)=>{
    console.log(error);
})

这样就可以根据res的值来确定结果了。resolve()对应then的结果,而reject()对应catch的结果。这在axios的请求操作中是十分常见的。

2.2 async 和 await

mdn描述如下:

async函数是使用async关键字声明的函数。 async函数是AsyncFunction构造函数的实例, 并且其中允许使用await关键字。async和await关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用promise。

async和await的关系:

async函数可能包含0个或者多个await表达式。await表达式会暂停整个async函数的执行进程并出让其控制权,只有当其等待的基于promise的异步操作被兑现或被拒绝之后才会恢复进程。promise的解决值会被当作该await表达式的返回值。使用async / await关键字就可以在异步代码中使用普通的try / catch代码块。

function getProcessedData(url) {
  return downloadData(url) // 返回一个 promise 对象
    .catch(e => {
      return downloadFallbackData(url)  // 返回一个 promise 对象
    })
    .then(v => {
      return processDataInWorker(v); // 返回一个 promise 对象
    });
}

使用async和await重写上述函数。

async function getProcessedData(url) {
  let v;
  try {
    v = await downloadData(url);
  } catch (e) {
    v = await downloadFallbackData(url);
  }
  return processDataInWorker(v);
}

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • javascript写的异步加载js文件函数(支持数组传参)

    自己用的加载js文件,支持多文件,不兼容ie 复制代码 代码如下: /** * 加载js文件 * @param  {string || array}   url   js路径 * @param  {Function} fn      加载完成后回调 * @return {object}           game对象 * @example * getScript("url.js",fn) * getScript(["url-1.js","url-2.js

  • 详解JavaScript异步编程中jQuery的promise对象的作用

    Promise, 中文可以理解为愿望,代表单个操作完成的最终结果.一个Promise拥有三种状态:分别是unfulfilled(未满足的).fulfilled(满足的).failed(失败的),fulfilled状态和failed状态都可以被监听.一个愿望可以从未满足状态变为满足或者失败状态,一旦一个愿望处于满足或者失败状态,其状态将不可再变化.这种"不可改变"的特性对于一个Promise来说非常的重要,它可以避免Promise的状态监听器修改一个Promise的状态导致别的监听器的行

  • 不同js异步函数同步的实现方法

    不同函数达到同步的函数模拟 funcList是函数执行函数的队列,其中回调函数中flag=true是同步标记量 <script> var flag = false; function funcTest(t,func){ setTimeout(function(){ (function(param){ console.log(param); func(); }(t)); },t*1000); } var funcList = []; funcList.push(function(){funcTe

  • javascript使用Promise对象实现异步编程

    Promise对象是CommonJS工作组为异步编程提供的统一接口,是ECMAScript6中提供了对Promise的原生支持,Promise就是在未来发生的事情,使用Promise可以避免回调函数的层层嵌套,还提供了规范更加容易的对异步操作进行控制.提供了reject,resolve,then和catch等方法. 使用PROMISE Promise是ES6之后原生的对象,我们只需要实例化Promise对象就可以直接使用. 实例化Promise: var promise = new Promis

  • 浅谈JavaScript中的对象及Promise对象的实现

    JavaScript 中的所有事物都是对象:字符串.数值.数组.函数.下面小编给大家收集整理些javascript中的对象及promise对象的实现.具体内容如下: 到处都是对象 window对象 常用的属性和方法介绍 location 包含页面的URL,如果改变这个属性,浏览器会访问新的URL status 包含将在浏览器状态去显示的一个串.一般在浏览器左下角 onload: 包含了需要在页面完全加载后调用的函数 document: 包含DOM alert方法: 显示一个提醒 prompt方法

  • 谈谈JavaScript异步函数发展历程

    <The Evolution of Asynchronous JavaScript>外文梳理了JavaScript异步函数的发展历程,首先通过回调函数实现异步,之后又经历了Promise/A+.生成器函数,而未来将是async函数的.感谢景庄对该文章的翻译,内容如下: 现在让我们一起来回顾这些年来JavaScript异步函数的发展历程吧. 回调函数Callbacks 似乎一切应该从回调函数开始谈起. 异步JavaScript 正如我们所知道的那样,在JavaScript中,异步编程方式只能通过

  • Javascript的异步函数和Promise对象你了解吗

    目录 1.JS中的异步 1.1同步 1.2异步 1.3回调函数解决异步问题 1.4回调地狱 2.Promise对象 2.1Promise的基本使用 2.2async和await 总结 1.JS中的异步 1.1 同步 一般情况下,js的代码都是自上而下顺序运行的.例如: let res = ''; res = '获取到的结果!'; console.log(res); 结果: 很容易理解,我给res赋了新值,然后输出res.这就是js的同步执行,这里的同步,并不是一起执行的意思,而是在一个线程里顺序

  • javascript中的糖衣语法Promise对象详解

    目录 一.Promise的诞生 1.回调地狱 二.Promise的行为 1.Promise的语法 2.Promise的方法 (1)Promise.prototype.then() (2)Promise.prototype.catch() (3)Promise.prototype.finally() (4)Promise.resolve() (5)Promise.reject() (6)Promise.all() (7)Promise.race() 三.Promise的场景 1.Ajax请求 2.

  • JavaScript中Function函数与Object对象的关系

    Function是javascript里最常用的一个概念,javascript里的function是最容易入手的一个功能,但它也是javascript最难理解最难掌握的一个概念. 今天我们来尝试理解Function和Object.因为这个里面有些人前期可能会搞糊涂.他们之间到底是什么关系.当然也不除外当初的我. 注意:官方定义: 在Javascript中,每一个函数实际上都是一个函数对象. 我们先来看最简单的两个代码,也是最容易理解的. function fn(){} var obj = {}

  • ES6 Promise对象的应用实例分析

    本文实例讲述了ES6 Promise对象的应用.分享给大家供大家参考,具体如下: The Promise object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value. Promise 对象用于一个异步操作的最终完成(或失败)及其结果值的表示.简单点说,它就是用于处理异步操作的,异步处理成功了就执行成功的操作,异步处理失败了就捕获错误或者停止

  • ES6基础之 Promise 对象用法实例详解

    本文实例讲述了ES6基础之 Promise 对象用法.分享给大家供大家参考,具体如下: Promise 对象 1.Promise对象是ES6对异步编程的一种解决方案,它有以下两个特点: Promise对象代表一个异步操作,它只有三种状态:Pending(进行中).Resolved(已完成,又称 Fulfilled)和Rejected(已失败),并且该状态不会受外界的影响 Promise对象的状态改变,只有两种可能:从 Pending 变为 Resolved 或者从 Pending 变为 Reje

  • ES6 Promise对象概念及用法实例详解

    本文实例讲述了ES6 Promise对象概念及用法.分享给大家供大家参考,具体如下: 参考文章:ECMAScript 6 入门 一. Promise是什么 Promise是异步编程的一种解决方案,它是一个容器,里面保存着某个未来才会结束的事件的结果.它有三种状态,只有异步操作的结果才能决定当前的状态,不受外界因素的影响.而一旦状态改变,就不会再变,也就是状态凝固了(resolved),任何时候都可以得到这个结果. Promise的缺点: 1. 无法取消Promise,一旦新建它就会立即执行,无法

  • es6中Promise 对象基本功能与用法实例分析

    本文实例讲述了es6中Promise 对象基本功能与用法.分享给大家供大家参考,具体如下: Promise 是异步编程的一种解决方案,解决--回调函数和事件 ES6 规定,Promise对象是一个构造函数,用来生成Promise实例. 下面代码创造了一个Promise实例. 基本用法 ES6 规定,Promise对象是一个构造函数,用来生成Promise实例. const promise = new Promise(function(resolve, reject) { //resolve (d

  • JavaScript中的函数模式详解

    JavaScript设计模式的作用是提高代码的重用性,可读性,使代码更容易的维护和扩展 在javascript中,函数是一类对象,这表示他可以作为参数传递给其他函数:此外,函数还可以提供作用域. 创建函数的语法 命名函数表达式 复制代码 代码如下: //命名函数表达式 var add = function add(a,b){     return a+b; }; 函数表达式 复制代码 代码如下: //又名匿名函数 var add = function(a,b){     return a+b;

随机推荐