1. 程式人生 > >異步實現方式

異步實現方式

his filled ice reac throw fin proto prototype amp

Promise異步實現方式:

var promise = new Promise(function (resolve, reject) {
    setTimeout(function () {
        resolve(‘success‘);
    }, 2000);
});

promise.then(function (msg) {
    console.log(msg);
}).catch(function (err) {
    console.log(err);
})

生成器異步實現方式:

function waitSeconds(ms) {
    return new
Promise(function (resolve, reject) { setTimeout(function () { resolve(‘success‘); }, ms); }) } function* gen() { var value = yield waitSeconds(2000); console.log(value); //2s後輸出‘success‘ } function run(gen) { return new Promise(function (resolve, reject) {
var g = gen(); function next(nextF) { try { var re = nextF(); } catch (e) { return reject(e); } if (re.done) { return resolve(re.value); } Promise.resolve(re.value).then(
function (v) { next(function () { return g.next(v); }) }, function (e) { next(function () { return g.throw(e); }) }) } next(function () { return g.next(); }) }) } run(gen);

async/await的異步實現:

function waitSeconds(ms) {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            resolve(‘success‘);
        }, ms);
    })
}

async function wait() {
    var value1 = await waitSeconds(2000);
    console.log(value1); // 2s後輸出‘success‘

    var value2 = await waitSeconds(3000);
    console.log(value2); // 2s+3s後輸出‘success‘
}

wait()

Promise原理(未整理完成):

function PromiseB(excutor) {
    var self = this;

    this._status = ‘pending‘;
    this.queue = [];

    excutor(function () {
        self.args = Array.prototype.slice.apply(arguments);
        self._status = ‘resolved‘;


        self.resolve.apply(self, self.args);
    }, function () {
        self.args = Array.prototype.slice.apply(arguments);
        self._status = ‘rejected‘;

        self.reject.apply(self, self.args);
    });


}



PromiseB.prototype.then = function (resolve, reject) {
    this.queue.push([resolve, reject]);
    return this;
}

PromiseB.prototype.resolve = function (value) {
    var self = this;

    this._next(0, value);
}

PromiseB.prototype.reject = function (err) {
    var self = this;

    this._next(1, err);
}

PromiseB.prototype._next = function (i, val) {

    var self = this,
        arr,
        fn,
        ret;


    setTimeout(function () {
        if(arr = self.queue.shift()) {
            fn = arr[i];
            ret = fn.call(self, val);

            if(!ret) return;

            if(ret instanceof PromiseB) {
                ret.queue = self.queue.slice();
                ret.then(ret.resolve, ret.reject);

            } else {
                self.resolve(ret);
            }
        }
    }, 0);



}

function PromiseD(fn) {
    var value = null,
        deferreds = [],
        state = ‘pending‘;

    this.then = function (onFulfilled, onRejected) {

        return new PromiseD(function (resolve, reject) {
            handle({
                onFulfilled: onFulfilled || null,
                onRejected: onRejected || null,
                resolve: resolve,
                reject: reject
            })
        })
    }


    function handle(deferred) {
        if(state === ‘pending‘) {
            deferreds.push(deferred);

            return;
        }

        var cb = state === ‘fulfilled‘ ? deferred.onFulfilled : deferred.onRejected,
            ret;

        if(cb === null) {
            cb = state ===‘fulfilled‘ ? deferred.resolve : deferred.reject;
            cb(value);
            return;
        }


        try {
            ret = cb(value);
            deferred.resolve(ret);
        } catch (e) {
            deferred.reject(e);
        }

    }

    function resolve(newValue) {

        if(newValue && (typeof newValue === ‘object‘ || typeof newValue === ‘function‘)) {
            var then = newValue.then;

            if(typeof then === ‘function‘) {
                then.call(newValue, resolve, reject);
                return;
            }
        }
        value = newValue;
        state = ‘fulfilled‘;

        finale();

    }

    function reject(reason) {
        state = ‘rejected‘;
        value = reason;
        finale();
    }

    function finale() {
        setTimeout(function () {
            deferreds.forEach(function (deferred) {
                handle(deferred);
            })
        }, 0);
    }


    fn(resolve, reject);
}

異步實現方式