promise/callback

164 阅读3分钟

同步与异步

javascript语言是一门“单线程”的语言,javascript就像一条流水线,仅仅是一条流水线而已,要么加工,要么包装,不能同时进行多个任务和流程,无论如何,js做事情的时候都是只有一条流水线(单线程),同步和异步的差别就在于这条流水线上各个流程的执行顺序不同。
同步任务:在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;
异步任务:不进入主线程、而进入"任务 队列"的任务,只有等主线程任务执行完毕,"任务队列"开始通知主线程,请求执行任务,该任务才会进入主线程执行。

回调函数

—函数当参数,传递另外一个函数
在JavaScript中,回调函数具体的定义为:函数A作为参数(函数引用)传递到另一个函数B中,并且这个函数B执行函数A。我们就说函数A叫做回调函数。如果没有名称(函数表达式),就叫做匿名回调函数。
但是回调函数有一个弊端,多层嵌套可读性很差,这个称之为 “回调地狱”

缺点:回调地狱,不能用 try catch 捕获错误,不能 return

回调地狱的根本问题在于:

  • 缺乏顺序性: 回调地狱导致的调试困难,和大脑的思维方式不符
  • 嵌套函数存在耦合性,一旦有所改动,就会牵一发而动全身,即(控制反转
  • 嵌套函数过多的多话,很难处理错误

回调函数简单应用
–回调函数将函数内部的值带出来

function fn(callback){
            $ajax({
                url:'数据接口地址',
                success:function(data){
                    let arrdata = JSON.parse(data);
                    callback(arrdata);
                }
            });
        }
        fn(function(d){
            console.log(d);
        });

–数组的一些方法:如every/some/filter/map/forEach

let arr = [1, 2, 3, 4];
        let arr2 = arr.filter((v) => {
            return v % 2;
        });
        console.log(arr2);

–定时器内部的函数
–事件处理回调函数

promise:异步编程的一种解决方案(es6)。可取代callback

     promise构造函数:比传统的回调函数更合理,更强大。

     创建promise实例对象,构造函数的参数又是一个函数对象,函数对象里面又有两个参数,一个 代表成功的回调,一个是失败的回调。

      promise状态:pending(进行中) resolve(成功,已解决) reject(失败,未解决)  , 状态一旦设定,不可改变。

      pending-->resolve 进行中-->成功

      pending-->reject 进行中-->失败

示例1
var promise = new Promise(function (resolve, reject) {
    //resolve:成功,名字等于函数体,reject:失败,一样的
  setTimeout(function () {
    console.log(1);
    // resolve(); //成功--then
    reject(); //失败--catch
    resolve('我是resolve'); //带参数 成功回调resolve函数只会执行一次
  }, 1000);
});

promise
  .then(function (str) { //成功的指向。 获取传递的参数。
    console.log(2);
    console.log(str); //我是resolve
  })
  .catch(function () { //失败的失败。
    console.log('出错啦');
  })
示例2
var promise = new Promise(function (resolve, reject) {
  let cImg = new Image();
  cImg.src = 'https://www.runoob.com/try/demo_source/logo.png';
  cImg.onload = function () {
    resolve(this);
  };
  cImg.onerror = function () {
    reject('路径错误');
  };
});
 promise.then(function (obj) {
  document.body.appendChild(obj);

}).catch(function (d) {
  alert(d);
});