search

Home  >  Q&A  >  body text

javascript - Doubts about Promise asynchronous operations, and how to write them more elegantly

function Promise(fn) {
  var state = 'pending';
  var value;
  var deferred = null;

  function resolve(newValue) {
    if(newValue && typeof newValue.then === 'function') {
      newValue.then(resolve, reject);
      return;
    }
    state = 'resolved';
    value = newValue;

    if(deferred) {
      handle(deferred);
    }
  }

  function reject(reason) {
    state = 'rejected';
    value = reason;

    if(deferred) {
      handle(deferred);
    }
  }

  function handle(handler) {
    if(state === 'pending') {
      deferred = handler;
      return;
    }

    var handlerCallback;

    if(state === 'resolved') {
      handlerCallback = handler.onResolved;
    } else {
      handlerCallback = handler.onRejected;
    }

    if(!handlerCallback) {
      if(state === 'resolved') {
        handler.resolve(value);
      } else {
        handler.reject(value);
      }

      return;
    }

    var ret = handlerCallback(value);
    handler.resolve(ret);
  }

  this.then = function(onResolved, onRejected) {
    return new Promise(function(resolve, reject) {
      handle({
        onResolved: onResolved,
        onRejected: onRejected,
        resolve: resolve,
        reject: reject
      });
    });
  };

  fn(resolve, reject);
}
大家讲道理大家讲道理2705 days ago870

reply all(3)I'll reply

  • 伊谢尔伦

    伊谢尔伦2017-07-05 11:06:56

    Promise was born to solve asynchronous flow control. The core of its use is the then method;
    then looks like a callback at first glance, but the characteristic of then is that it can handle exceptions and chain writing.
    For example, a few The ajax request dependencies are as follows:

    A1 -> A2;
    Aa -> Ab;
    Ab + Ac -> Ad;
    A2 + Ad -> Ax;

    If you use Promise, the code will be very clear
    First prepare A1, A2, Aa, Ab, Ac, Ad, and Ax. They are all functions that return promise objects based on dependencies. I won’t write them anymore. Then you can watch the Promise performance. :

    Promise.all([
        A1().then(A2),      //A1 -> A2
        Promise.all([
            Aa().then(Ab),  //Aa -> Ab
            Ac()            //Ac
        ]).then(Ad)         //Ab + Ac -> Ad;
    ]).then(Ax,Err)         //A2 + Ad -> Ax
    .then(function(v){
    //完成
    })

    A1, Aa and Ac have no dependencies and will be executed concurrently, and will continue based on the completion of dependencies.

    No matter which Ajax problem occurs, the final Err event will be triggered to handle the error uniformly;
    If you use a callback to write it Try it, either the efficiency is not good, or a bunch of code is added to the callback method to determine the dependency.

    Reference code:

    //首先准备好 A1,A2,Aa,Ab,Ac,Ad,Ax 都是基于回调的异步函数
    var a2,ab,ac,ad;  //用来保存完成情况的变量
    function runAx(){
        if(a2 == undefined || ad == undefined) return; //判断依赖
        Ax(a2,ad,function(e,v){
            //完成
        })
    }
    function runAd(){
        if(ab == undefined || ac == undefined) return; //判断依赖
        Ad(ab,ac,function(e,v){
            ad = v;
            runAx();
        })
    }
    A1(function(e,v){   
        A2(v,function(e,v){
            a2 = v;
            runAx();
        })
    })
    Aa(function(e,v){
        Ab(v,function(e,v){
            ab = v;
            runAd();
        })
    })
    Ac(function(e,v){
        ac = v;
        runAd();
    })

    The above code does not handle errors and is so long. If the dependencies were more complicated, you can imagine the amount of code and it is easy to write errors;

    reply
    0
  • 为情所困

    为情所困2017-07-05 11:06:56

    Your understanding is basically correct. In fact, Promise is not much simplified, it just reduces the nesting level.

    So, the ultimate solution is Async/Await, the questioner can check the information.

    reply
    0
  • 怪我咯

    怪我咯2017-07-05 11:06:56

    Elegance is one then after another, straightening the callback Christmas tree shape. This is the contribution of Promises.

    When I write a program, I need to nest seven or eight callbacks, and Promises is much better.

    If you think writing then is too troublesome, then don’t use it, use Async/Await

    reply
    0
  • Cancelreply