javascript-异步编程

在编程中什么是同步和异步?
同步(Synchronous):就是在发出一个功能调用时,在没有得到结果之前,该调用就不会返回。
按照这个定义,其实绝大多数函数都是同步调用。但是一般而言,我们在说同步、异步的时候,特
指那些需要其他部件协作或者需要一定时间完成的任务。
异步(ASynchronous):异步则和同步相反,当一个异步功能调用发出后,调用者不能立刻得到结果。
当该异步功能完成后,通过状态、通知或回调来通知调用者。如果异步功能用状态来通知,那么调用者就
需要每隔一定时间检查一次,效率就很低(有些初学多线程编程的人,总喜欢用一个循环去检查某个变量
的值,这其实是一 种很严重的错误)。如果是使用通知的方式,效率则很高,因为异步功能几乎不需要做额外的操作。至于回调函数,其实和通知没太多区别
什么时候需要用到异步编程?
处理一些简短,快速的操作时(例如:1+1的结果),往往主线程就可以完成,当遇到多方面的请求,主线程不能同时处理,
必须等待一个请求完成后才可以处理其他请求。
有一个按钮,onclick事件为一个死循环,当按下按钮后,整个页面将失去响应,因为在等待循环结束。
为了避免这种情况,我们可以用子线程来完成一些消耗时间比较长的事情,比如读取大文件,发出网络请求(需等待服务器响应),
这样不会占用主线程的运行,可以通过回调函数来处理异步任务的结果
回调函数:回调函数就是一个函数,它是在我们启动一个异步任务的时候就告诉它:等你完成了这个任务之后要干什么。这样一来主线程几乎不用关心异步任务的状态了,他自己会善始善终。

怎么用?

//这里我们做个实例来模拟一下异步任务结束,回调函数的实现过程
/*这里我们用setTimeout()函数来模拟一个请求,第一个参数是回调函数,第二个参数是延时,
过程就是异步挂起一个任务继续执行主线程的代码,等到该任务返回结果后(这里用延时3秒来模拟
服务器返回结果),在通过回调函数来处理,这样主线程就不必等待该任务结束的时间。*/ <script> function print() { document.getElementById("demo").innerHTML="RUNOOB!"; } setTimeout(print, 3000); document.write("主线程"); </script>

//第二种方法,不必特意去定义一个print函数

setTimeout(function () {
  document.getElementById("demo").innerHTML="RUNOOB!";
}, 3000);
上面实例处理了一个异步任务,当需要处理多个异步任务的时候很不方便,例如想使用异步函数分三次间隔时间去打印字符串
setTimeout(function () {
    console.log("First");
    setTimeout(function () {
        console.log("Second");
        setTimeout(function () {
            console.log("Third");
        }, 3000);
    }, 4000);
}, 1000);
//可以看到使用这种瀑布型写法,非常不易阅读,也不美观,更加无法进行异常处理
这时我们可以用Promise对象
Promise 是一个 ECMAScript 6 提供的类,目的是更加优雅地书写复杂的异步任务。
//构造Promise
new Prominse(function (resolve, reject)    {
    //要做的事情。。。
});



Promise 的使用
Javascript执行环境是单线程的,也就是说JS环境中负责解释和执行的线程只有一个,一次只能完成一项任务,
这个任务执行完后才能执行下一个,因此Javascript中存在大量的异步操作和回调函数。
Promise函数是异步编程的一个解决方案,相对传统的解决方案,他更合理和强大。
Promise的本意是“承诺”、“许诺”的意思。承诺在未来会执行某个操作的函数,就是Promise函数。其基本结构如下:

var promise = new Promise(function(resolve, reject){
  // ...你的代码
  if (/*异步成功*/){
    resolve(value);
  } else{
    reject(error);
  }
});

 Promise的状态

Promise对象的状态有3个,分别是pending(进行中)、fulfilled(已完成)、rejected(已失败)。Promise对象一旦进入了某一个状态,就不会再转成其他状态了(主要是后面两种状态,fulfilled和rejected)。如一旦调用了resolve函数,就是fulfilled的状态,就不会再调用reject函数了。

pending:等待状态,比如正在进行网络请求,或者定时器没有到时间。

fulfilled:满足状态,当我们回调了resolve函数时,就处于该状态。

rejected:拒绝状态,当我们回调了reject函数时,就处于该状态。

let p = new Promise((resolve, reject) => {
    let a1 = '成功的参数';
    let a2 = '失败的参数';
    var time = setTimeout(() => {
        console.log('start');
        resolve(a1);
        reject(a2);
        console.log('end');
    }, 1000);
});
 
p.then(value => {
    console.log('这是resolve函数体,参数:' + value);
}, reason => {
    console.log('这是reject函数体,参数:' + reason);
通过回调里的 resolve(data) 将这个 promise 标记为 resolverd,然后进行下一步 then((data)=>{//do something}),resolve 里的参数就是你要传入 then 的数据。


内容参考:
https://blog.csdn.net/tuolingss/article/details/104374741
http://www.runoob.com/js/js-promise.html




posted @ 2021-05-14 15:10  _cai  阅读(68)  评论(0编辑  收藏  举报