异步实现方式

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);
}

 

posted on 2017-05-11 17:54  zmiaozzz  阅读(990)  评论(0编辑  收藏  举报

导航