韦德国际1946英国 > 计算机网络 > 关于promise的详细讲解

原标题:关于promise的详细讲解

浏览次数:179 时间:2019-08-31

// From Jake Archibald's Promises and Back:
// http://www.html5rocks.com/en/tutorials/es6/promises/#toc-promisifying-xmlhttprequest

function get(url) {
 // Return a new promise.
 return new Promise(function(resolve, reject) {
  // Do the usual XHR stuff
  var req = new XMLHttpRequest();
  req.open('GET', url);

  req.onload = function() {
   // This is called even on 404 etc
   // so check the status
   if (req.status == 200) {
    // Resolve the promise with the response text
    resolve(req.response);
   }
   else {
    // Otherwise reject with the status text
    // which will hopefully be a meaningful error
    reject(Error(req.statusText));
   }
  };

  // Handle network errors
  req.onerror = function() {
   reject(Error("Network Error"));
  };

  // Make the request
  req.send();
 });
}

// Use it!
get('story.json').then(function(response) {
 console.log("Success!", response);
}, function(error) {
 console.error("Failed!", error);
});
Promise.race

Promise.race 是叁个有趣的函数. 与 Promise.all 相反, 只要有些 priomise 被 resolved 或许 rejected, 就能够触发 Promise.race:

    var req1 = new Promise(function(resolve, reject) { 
        // 通过 setTimeout 模拟异步任务
        setTimeout(function() { resolve('First!'); }, 8000);
    });
    var req2 = new Promise(function(resolve, reject) { 
        // 通过 setTimeout 模拟异步任务
        setTimeout(function() { resolve('Second!'); }, 3000);
    });
    Promise.race([req1, req2]).then(function(one) {
        console.log('Then: ', one);
    }).catch(function(one, two) {
        console.log('Catch: ', one);
    });

    // From the console:
    // Then: Second!

三个案例是呼吁的财富有 主站能源和备用财富(以免某些不可用)。
改变习贯, 使用 Promise
在过去几年中 Promise 一贯是个热点话题(要是你是 Dojo Toolkit 顾客,那么正是已经有10年了), 已经从二个JavaScript框架造成了语言的二个重大成分. 异常的快你就会见到大非常多新的 JavaScript api 都会依靠 Promise 的办法来兑现……
... 当然那是一件好事! 开采职员能够逃脱回调的鬼世界, 异步交互也能够像别的变量一样传递. Promise 还亟需一段时间来推广, 以往是时候去读书他们了!

then

各类 promise 实例都有 then 方法, 用来管理实践结果。 第三个 then 方法回调的参数, 正是 resolve() 传入的要命值:

    new Promise(function(resolve, reject) {
        // 通过 setTimeout 模拟异步任务
        setTimeout(function() { resolve(10); }, 3000);
    })
    .then(function(result) {
        console.log(result);
    });

    // console 输出的结果:
    // 10

then 回调由 promise 的 resolved 触发。你也足以采纳链式的 then` 回调方法:

    new Promise(function(resolve, reject) { 
        // 通过 setTimeout 模拟异步任务
        setTimeout(function() { resolve(10); }, 3000);
    })
    .then(function(num) { console.log('first then: ', num); return num * 2; })
    .then(function(num) { console.log('second then: ', num); return num * 2; })
    .then(function(num) { console.log('last then: ', num);});

    // console 输出的结果:
    // first then:  10
    // second then:  20
    // last then:  40

各类 then 收到的结果都以前面那多少个 then 重回的值。
万一 promise 已经 resolved, 但之后才调用 then 方法, 则登时触发回调。假设promise被拒绝之后才调用 then, 则回调函数不会被触发。

Promise.all([fetch('/users.json'), navigator.getBattery()]).then(function(results) {
 // Both promises done!
});

所在是回调函数,代码非常臃肿难看, Promise 首要用来消除这种编制程序方式, 将或多或少代码封装于当中。

虽说联合代码更易于追踪和调和, 但异步形式却有着越来越好的性质与灵活性. 怎么着在同等时刻发起五个恳求, 然后分别管理响应结果? Promise 现已成为 JavaScript 中国和北美洲常首要的二个组成都部队分, 非常多新的API都是 promise 的章程来贯彻。上面简单介绍 promise, 以及对应的 API 和利用示例!

XMLHttpRequest API是异步的,但它从未利用promise API。但有很多原生的 javascript API 使用了promise:

代码的可读性非常首要,因为开采人士支出一般比Computer硬件的开销要大过多倍。

catch

当 promise 被拒绝时, catch 回调就可以被实施:

    new Promise(function(resolve, reject) {
        // 通过 setTimeout 模拟异步任务
        setTimeout(function() { reject('Done!'); }, 3000);
    })
    .then(function(e) { console.log('done', e); })
    .catch(function(e) { console.log('catch: ', e); });

    // console 输出的结果:
    // 'catch: Done!'

流传 reject 方法的参数由你本人说了算。一般的话是传播贰个 Error 对象:

    reject(Error('Data could not be found'));
var request1 = fetch('/users.json');
var request2 = fetch('/articles.json');

Promise.all([request1, request2]).then(function(results) {
 // Both promises done!
});
then

各种 promise 实例都有 then 方法, 用来管理试行结果。 第二个 then 方法回调的参数, 正是 resolve() 传入的不行值:

    new Promise(function(resolve, reject) {
        // 通过 setTimeout 模拟异步任务
        setTimeout(function() { resolve(10); }, 3000);
    })
    .then(function(result) {
        console.log(result);
    });

    // console 输出的结果:
    // 10

then 回调由 promise 的 resolved 触发。你也足以应用链式的 then` 回调方法:

    new Promise(function(resolve, reject) { 
        // 通过 setTimeout 模拟异步任务
        setTimeout(function() { resolve(10); }, 3000);
    })
    .then(function(num) { console.log('first then: ', num); return num * 2; })
    .then(function(num) { console.log('second then: ', num); return num * 2; })
    .then(function(num) { console.log('last then: ', num);});

    // console 输出的结果:
    // first then:  10
    // second then:  20
    // last then:  40

种种 then 收到的结果都以在此之前那个 then 再次来到的值。
只要 promise 已经 resolved, 但之后才调用 then 方法, 则立即触发回调。假如promise被驳回之后才调用 then, 则回调函数不会被触发。

Promise.race

Promise.race 是一个有趣的函数. 与 Promise.all 相反, 只要某些 priomise 被 resolved 可能 rejected, 就能够触发 Promise.race:

    var req1 = new Promise(function(resolve, reject) { 
        // 通过 setTimeout 模拟异步任务
        setTimeout(function() { resolve('First!'); }, 8000);
    });
    var req2 = new Promise(function(resolve, reject) { 
        // 通过 setTimeout 模拟异步任务
        setTimeout(function() { resolve('Second!'); }, 3000);
    });
    Promise.race([req1, req2]).then(function(one) {
        console.log('Then: ', one);
    }).catch(function(one, two) {
        console.log('Catch: ', one);
    });

    // From the console:
    // Then: Second!

贰个案例是伸手的财富有 主站能源和备用能源(防止某些不可用)。
转移习于旧贯, 使用 Promise
在过去几年中 Promise 从来是个火热话题(倘使您是 Dojo Toolkit 客户,那么就是现已有10年了), 已经从二个JavaScript框架变成了言语的三个最首要成分. 非常快你就能够看出大好些个新的 JavaScript api 都会基于 Promise 的法门来兑现……
... 当然这是一件好事! 开辟人士能够避开回调的苦海, 异步交互也能够像其余变量同样传递. Promise 还索要一段时间来推广, 现在是时候去上学他们了!

Promise.all 方法

就算如此联合代码更易于追踪和调解, 但异步方式却持有越来越好的性格与灵活性. 怎么样在一样时刻发起七个要求, 然后各自管理响应结果? Promise 现已改为 JavaScript 中这一个关键的一个组成都部队分, 非常多新的API都是 promise 的格局来完成。上面简介 promise, 以及对应的 API 和平运动用示例!

Promise 直译为“承诺”,但一般间接称为 Promise;

Promise.race

Promises 周边

XMLHttpRequest 是异步API, 但不算 Promise 格局。当前应用 Promise 的原生 api 满含:
•Battery API
•fetch API (用来代表 XH揽胜)
•ServiceWorker API

Promise 会越来越流行,所在此之前端开辟须要连忙调节它们。当然, Node.js 是另七个应用 Promise 的阳台(明显, Promise 在Node中是七个核心天性)。
测验 promises 只怕比你想象的还要轻易, 因为 setTimeout 能够用来作为异步“任务”!

代码的可读性特别关键,因为开采人士支出一般比Computer硬件的支出要大过多倍。

咱俩还可将fetch和电瓶状态API混合一齐施行,因为它们再次来到的都以 promise:

catch

当 promise 被驳回时, catch 回调就能够被试行:

    new Promise(function(resolve, reject) {
        // 通过 setTimeout 模拟异步任务
        setTimeout(function() { reject('Done!'); }, 3000);
    })
    .then(function(e) { console.log('done', e); })
    .catch(function(e) { console.log('catch: ', e); });

    // console 输出的结果:
    // 'catch: Done!'

流传 reject 方法的参数由你和煦主宰。一般的话是流传二个 Error 对象:

    reject(Error('Data could not be found'));

Promises 周边

XMLHttpRequest 是异步API, 但不算 Promise 情势。当前利用 Promise 的原生 api 包含:
•Battery API
•fetch API (用来代替 XHRAV4)
•ServiceWorker API

关于promise的详细讲解。Promise 会越来越流行,所从前端开垦要求急迅了然它们。当然, Node.js 是另三个应用 Promise 的平台(分明, Promise 在Node中是一个大旨天性)。
测验 promises 恐怕比你想像的还要轻易, 因为 setTimeout 可以用来作为异步“职分”!

Promise.race 是一个有趣的函数——它不是伺机全数的 promise 被resolve 或 reject,而是在富有的 promise 中只要有四个实践达成,它就能接触:

Promise 基本用法

间接利用 new Promise() 构造函数的主意, 应该只用来拍卖遗留的异步职务编程, 比如 set提姆eout大概 XMLHttpRequest。 通过 new 关键字成立二个新的 Promise 对象, 该对象有 resolve(化解!) 和 reject(拒绝!) 多个回调函数:

    var p = new Promise(function(resolve, reject) {
        // ... ... 
        // 此处,可以执行某些异步任务,然后...
        // 在回调中,或者任何地方执行 resolve/reject

        if(/* good condition */) {
            resolve('传入成果结果信息,如 data');
        }
        else {
            reject('失败:原因...!');
        }
    });

    p.then(function(data) { 
        /* do something with the result */
    }).catch(function(err) {
        /* error :( */
    });

貌似是由开采职员遵照异步职务实行的结果,来手动调用 resolve 恐怕 reject. 一个天下第一的例证是将 XMLHttpRequest 转变为根据Promise的任务:

// 本段示例代码来源于 Jake Archibald's Promises and Back:
// http://www.html5rocks.com/en/tutorials/es6/promises/#toc-promisifying-xmlhttprequest

    function get(url) {
        // 返回一个 promise 对象.
        return new Promise(function(resolve, reject) {
            // 执行常规的 XHR 请求
            var req = new XMLHttpRequest();
            req.open('GET', url);

            req.onload = function() {
            // This is called even on 404 etc
            // so check the status
            if (req.status == 200) {
            // Resolve the promise with the response text
            resolve(req.response);
            }
            else {
            // Otherwise reject with the status text
            // which will hopefully be a meaningful error
            reject(Error(req.statusText));
            }
            };

            // Handle network errors
            req.onerror = function() {
            reject(Error("网络出错"));
            };

            // Make the request
            req.send();
        });
    };

    // 使用!
    get('story.json').then(function(response) {
    console.log("Success!", response);
    }, function(error) {
    console.error("Failed!", error);
    });

有时在 promise 方法体中没有必要进行异步任务 —— 当然,在有非常大概率会推行异步职责的事态下, 重临 promise 将是最棒的诀要, 那样只供给加以结果管理函数就行。在这种景况下, 无需运用 new 关键字, 直接重返 Promise.resolve() 恐怕 Promise.reject()就可以。例如:

    var userCache = {};

    function getUserDetail(username) {
    // In both cases, cached or not, a promise will be returned

    if (userCache[username]) {
        // Return a promise without the "new" keyword
        return Promise.resolve(userCache[username]);
    }

    // Use the fetch API to get the information
    // fetch returns a promise
    return fetch('users/'   username   '.json')
        .then(function(result) {
        userCache[username] = result;
        return result;
        })
        .catch(function() {
        throw new Error('Could not find user: '   username);
        });
    };

因为延续会回来 promise, 所以只须要通过 then 和 catch 方法管理结果就能够!

Promise.all

想想JavaScript加载器的意况: 一时候会接触两个异步交互, 但只在具备乞请达成未来才会做出响应。—— 这种境况能够利用 Promise.all 来管理。Promise.all 方法接受三个 promise 数组, 在颇具 promises 都解决之后, 触发一个回调:

    Promise.all([promise1, promise2]).then(function(results) {
        // Both promises resolved
    })
    .catch(function(error) {
        // One or more promises was rejected
    });

Promise.all 的特级示例是通过fetch同一时间提倡多少个 AJAX诉求时:

    var request1 = fetch('/users.json');
    var request2 = fetch('/articles.json');

    Promise.all([request1, request2]).then(function(results) {
        // Both promises done!
    });

你也得以整合使用 fetch 和 Battery 之类的 API ,因为她俩都回去 promises:

    Promise.all([fetch('/users.json'), navigator.getBattery()]).then(function(results) {
        // Both promises done!
    });
    当然, 处理拒绝的情况比较复杂。如果某个 promise 被拒绝, 则 catch 将会被第一个拒绝(rejection)所触发:
    var req1 = new Promise(function(resolve, reject) { 
        // 通过 setTimeout 模拟异步任务
        setTimeout(function() { resolve('First!'); }, 4000);
    });
    var req2 = new Promise(function(resolve, reject) { 
        // 通过 setTimeout 模拟异步任务
        setTimeout(function() { reject('Second!'); }, 3000);
    });
    Promise.all([req1, req2]).then(function(results) {
        console.log('Then: ', one);
    }).catch(function(err) {
        console.log('Catch: ', err);
    });

    // From the console:
    // Catch: Second!

乘机更多的 API 帮忙 promise, Promise.all 将会变得最棒有用。

Promises的用法比你想象的要简明——若是您从前喜欢使用setTimeout来调整异步职分的话!

Promise.all

想想JavaScript加载器的状态: 一时候会接触三个异步交互, 但只在具备央浼完成以往才会做出响应。—— 这种情景能够运用 Promise.all 来管理。Promise.all 方法接受贰个 promise 数组, 在装有 promises 都化解之后, 触发叁个回调:

    Promise.all([promise1, promise2]).then(function(results) {
        // Both promises resolved
    })
    .catch(function(error) {
        // One or more promises was rejected
    });

Promise.all 的最好示例是因而fetch同时提倡多少个 AJAX央求时:

    var request1 = fetch('/users.json');
    var request2 = fetch('/articles.json');

    Promise.all([request1, request2]).then(function(results) {
        // Both promises done!
    });

您也足以组合使用 fetch 和 Battery 之类的 API ,因为他俩都回去 promises:

    Promise.all([fetch('/users.json'), navigator.getBattery()]).then(function(results) {
        // Both promises done!
    });
    当然, 处理拒绝的情况比较复杂。如果某个 promise 被拒绝, 则 catch 将会被第一个拒绝(rejection)所触发:
    var req1 = new Promise(function(resolve, reject) { 
        // 通过 setTimeout 模拟异步任务
        setTimeout(function() { resolve('First!'); }, 4000);
    });
    var req2 = new Promise(function(resolve, reject) { 
        // 通过 setTimeout 模拟异步任务
        setTimeout(function() { reject('Second!'); }, 3000);
    });
    Promise.all([req1, req2]).then(function(results) {
        console.log('Then: ', one);
    }).catch(function(err) {
        console.log('Catch: ', err);
    });

    // From the console:
    // Catch: Second!

乘胜越来越多的 API 扶助 promise, Promise.all 将会变得最棒有用。

中国人民解放军第四野战军是回调函数,代码非常臃肿难看, Promise 主要用来消除这种编制程序方式, 将或多或少代码封装于在那之中。

var req1 = new Promise(function(resolve, reject) { 
 // A mock async action using setTimeout
 setTimeout(function() { resolve('First!'); }, 4000);
});
var req2 = new Promise(function(resolve, reject) { 
 // A mock async action using setTimeout
 setTimeout(function() { reject('Second!'); }, 3000);
});
Promise.all([req1, req2]).then(function(results) {
 console.log('Then: ', one);
}).catch(function(err) {
 console.log('Catch: ', err);
});

// From the console:
// Catch: Second!

Promise 直译为“承诺”,但貌似直接称为 Promise;

Promise 基本用法

直白动用 new Promise() 构造函数的主意, 应该只用来管理遗留的异步职分编制程序, 比如 setTimeout或许 XMLHttpRequest。 通过 new 关键字创造三个新的 Promise 对象, 该对象有 resolve(解决!) 和 reject(拒绝!) 三个回调函数:

    var p = new Promise(function(resolve, reject) {
        // ... ... 
        // 此处,可以执行某些异步任务,然后...
        // 在回调中,或者任何地方执行 resolve/reject

        if(/* good condition */) {
            resolve('传入成果结果信息,如 data');
        }
        else {
            reject('失败:原因...!');
        }
    });

    p.then(function(data) { 
        /* do something with the result */
    }).catch(function(err) {
        /* error :( */
    });

貌似是由开采职员依照异步职分推行的结果,来手动调用 resolve 可能 reject. 二个天下第一的例子是将 XMLHttpRequest 转变为基于Promise的任务:

// 本段示例代码来源于 Jake Archibald's Promises and Back:
// http://www.html5rocks.com/en/tutorials/es6/promises/#toc-promisifying-xmlhttprequest

    function get(url) {
        // 返回一个 promise 对象.
        return new Promise(function(resolve, reject) {
            // 执行常规的 XHR 请求
            var req = new XMLHttpRequest();
            req.open('GET', url);

            req.onload = function() {
            // This is called even on 404 etc
            // so check the status
            if (req.status == 200) {
            // Resolve the promise with the response text
            resolve(req.response);
            }
            else {
            // Otherwise reject with the status text
            // which will hopefully be a meaningful error
            reject(Error(req.statusText));
            }
            };

            // Handle network errors
            req.onerror = function() {
            reject(Error("网络出错"));
            };

            // Make the request
            req.send();
        });
    };

    // 使用!
    get('story.json').then(function(response) {
    console.log("Success!", response);
    }, function(error) {
    console.error("Failed!", error);
    });

突发性在 promise 方法体中无需实行异步任务 —— 当然,在有望会推行异步职责的景况下, 重临 promise 将是最佳的法门, 那样只必要加以结果处理函数就行。在这种气象下, 无需利用 new 关键字, 间接重返 Promise.resolve() 也许 Promise.reject()就能够。举例:

    var userCache = {};

    function getUserDetail(username) {
    // In both cases, cached or not, a promise will be returned

    if (userCache[username]) {
        // Return a promise without the "new" keyword
        return Promise.resolve(userCache[username]);
    }

    // Use the fetch API to get the information
    // fetch returns a promise
    return fetch('users/'   username   '.json')
        .then(function(result) {
        userCache[username] = result;
        return result;
        })
        .catch(function() {
        throw new Error('Could not find user: '   username);
        });
    };

因为接二连三会回来 promise, 所以只须要通过 then 和 catch 方法管理结果就能够!

学会使用 Promises

new Promise(function(resolve, reject) {
 // A mock async action using setTimeout
 setTimeout(function() { resolve(10); }, 3000);
})
.then(function(result) {
 console.log(result);
});

// From the console:
// 10

普普通通我们在 reject 方法里处理施行倒闭的结果,而在catch 里施行分外结果:

如若 promise 里调用了reject函数,也等于执行被驳回了,未有能够正常达成,意况会略带复杂。一旦 promise 被拒绝,catch 方法会捕捉到第二个被执行的reject函数:

catch 方法

本文由韦德国际1946英国发布于计算机网络,转载请注明出处:关于promise的详细讲解

关键词: JavaScript

上一篇:计算机网络:jquery中的常见问题及快速解决方法

下一篇:没有了