个性化阅读
专注于IT技术分析

JavaScript如何将现有的回调API转为promise?有示范实例吗?

JavaScript如何将现有的回调API转为promises?有示范实例吗?我想使用promise,现在有一个回调API,格式是这样的:

1、DOM加载或其它一次性事件

window.onload; // 设置回调
// 其它代码
window.onload = function() {

};

2、简单的回调

function request(onChangeHandler) {
    // 代码块
}
request(function() {
    // 代码更改
    // 实现代码
});

3、Node风格回调

function getStuff(dat, callback) {
    ...
}
getStuff("dataParam", function(err, data) {
    ...
})

4、整个库都使用Node风格回调

API;
API.one(function(err, data) {
    API.two(function(err, data2) {
        API.three(function(err, data3) {
            ...
        });
    });
});

如何在promise中使用API?

promise都有状态,它们以pending开始,并可以稳定到:completed表示计算成功完成。拒绝意味着计算失败。promise返回函数不应该抛出,而是应该返回拒绝。抛出promise返回函数将迫使你同时使用}catch和.catch。使用promise api的人不希望promise抛出。如果你不确定异步api在JS中是如何工作的,请先看看这个答案。

1. DOM加载或其他一次性事件

因此,创建promise通常意味着指定它们何时解决—这意味着它们何时移动到已完成或已拒绝阶段,以表明数据可用(并且可以使用then访问)。使用支持promise构造函数的现代promise实现,比如原生ES6 promise

function load() {
    return new Promise(function(resolve, reject) {
        window.onload = resolve;
    });
}

然后你可以这样产生promise:

load().then(function() {
    // 加载完成执行
});

使用支持延迟的库,这里使用jQuery:

function load() {
    var d = $q.defer();
    window.onload = function() { d.resolve(); };
    return d.promise;
}

或者使用jQuery之类的API,挂接一次性事件

function done() {
    var d = $.Deferred();
    $("#myObject").once("click",function() {
        d.resolve();
    });
    return d.promise();
}

2、普通回调

这些API很常见,因为良好的回调在JS中很常见,看看onSuccess和onFail的使用:

function getUserData(userId, onLoad, onFail) { …

使用支持promise构造函数的现代promise实现,比如原生ES6 promise

function getUserDataAsync(userId) {
    return new Promise(function(resolve, reject) {
        getUserData(userId, resolve, reject);
    });
}

使用支持异步的库

function getUserDataAsync(userId) {
    var d = $.Deferred();
    getUserData(userId, function(res){ d.resolve(res); }, function(err){ d.reject(err); });
    return d.promise();
}

jQuery还提供了一个$.Deferred(fn)表单,它的优点是允许我们编写一个表达式,该表达式非常接近new Promise(fn)表单,如下所示

function getUserDataAsync(userId) {
    return $.Deferred(function(dfrd) {
        getUserData(userId, dfrd.resolve, dfrd.reject);
    }).promise();
}

注意:这里我们利用了jQuery延迟解析和拒绝方法是“可分离的”这一事实。它们被绑定到jQuery.Deferred()的实例。并不是所有lib都提供这个特性。

3.节点样式回调(“nodeback”)

节点样式回调(nodebacks)具有特定的格式,其中回调总是最后一个参数,它的第一个参数是一个错误。我们先手动约定一个

getStuff("dataParam", function(err, data) { …

    function getStuffAsync(param) {
        return new Promise(function(resolve, reject) {
            getStuff(param, function(err, data) {
                if (err !== null) reject(err);
                else resolve(data);
            });
        });
    }

使用延迟可以执行以下操作

function getStuffAsync(param) {
    var d = Q.defer();
    getStuff(param, function(err, data) {
        if (err !== null) d.reject(err);
        else d.resolve(data);
    });
    return d.promise;   
}
赞(0)
未经允许不得转载:srcmini » JavaScript如何将现有的回调API转为promise?有示范实例吗?

评论 抢沙发

评论前必须登录!