使用ES6承诺,如何在不定义解析逻辑的情况下创建承诺?这是一个基本的例子(一些TypeScript):
var promises = {};
function waitFor(key: string): Promise<any> {
if (key in promises) {
return promises[key];
}
var promise = new Promise(resolve => {
// But I don't want to try resolving anything here :(
});
promises[key] = promise;
return promise;
}
function resolveWith(key: string, value: any): void {
promises[key].resolve(value); // Not valid :(
}
Run Code Online (Sandbox Code Playgroud)
使用其他promise库可以轻松完成.以JQuery为例:
var deferreds = {};
function waitFor(key: string): Promise<any> {
if (key in promises) {
return deferreds[key].promise();
}
var def = $.Deferred();
deferreds[key] = …Run Code Online (Sandbox Code Playgroud) 使用Promises时,为什么不能在代码库的其他地方触发resolve和reject定义?
我不明白为什么resolve和reject逻辑应该在声明promise的地方进行本地化.这是一种疏忽,还是强制要求executor参数?
我相信执行程序函数应该是可选的,并且它的存在应该确定promise是否封装了解决方案.如果没有这样的要求,承诺将更加可扩展,因为您不必立即启动异步.承诺也应该是可以重置的.它是一个1开关,1或0,resolve()或reject().有迹象表明,可附接的并行和串行结果众多:promise.then(parallel1)和promise.then(parallel2)并且也promise.then(seq1).then(seq2)但参考特权玩家无法解析/拒绝到交换机
您可以在以后构建结果树,但不能改变它们,也不能改变根(输入触发器)
老实说,连续结果的树也应该是可编辑的.假设你想要拼出一个步骤并在你宣布许多承诺链之后做其他事情.重建承诺和每个顺序功能是没有意义的,特别是因为你甚至不能拒绝或毁掉承诺......
问题1:在给定时间只允许一个API请求,因此真实的网络请求排队,而尚未完成的请求.应用程序可以随时调用API级别并期望获得回报.当API调用排队时,将在未来的某个时刻创建网络请求的承诺 - 返回应用程序的内容是什么?这就是如何通过延迟的"代理"承诺来解决它:
var queue = [];
function callAPI (params) {
if (API_available) {
API_available = false;
return doRealNetRequest(params).then(function(data){
API_available = true;
continueRequests();
return data;
});
} else {
var deferred = Promise.defer();
function makeRequest() {
API_available = false;
doRealNetRequest(params).then(function(data) {
deferred.resolve(data);
API_available = true;
continueRequests();
}, deferred.reject);
}
queue.push(makeRequest);
return deferred.promise;
}
}
function continueRequests() {
if (queue.length) {
var makeRequest = queue.shift();
makeRequest();
}
}
Run Code Online (Sandbox Code Playgroud)
问题2:某些API调用被去抖动,因此要发送的数据会随着时间的推移而累积,然后在达到超时时批量发送.调用API的应用程序期待作为回报的承诺.
var queue = null;
var timeout = 0;
function callAPI2(data) {
if …Run Code Online (Sandbox Code Playgroud) 我正在使用es6,并希望创建一个延迟确认对话框:
// First, create an empty promise:
let promise = new Promise((resolve, reject) => {})
// Then, show the dialog:
let $dialog = $('#dialog-confirm').show();
// FAIL: I want to trigger the promise resolver, but failed.
$dialog.find('.btn-yes').click(() => { promise.resolve(); })
$dialog.find('.btn-no').click(() => { promise.reject(); })
Run Code Online (Sandbox Code Playgroud)
当我单击按钮时,它失败了,因为Promise没有rejectand resolve方法。
未被捕获的TypeError:promise.resolve不是一个函数(…)
如果使用jQuery,我们可以执行以下操作:
// First, create an empty promise:
var dfd = $.Deferred();
var promise = dfd.promise();
// Then, show the dialog:
var $dialog = $('#dialog-confirm').show();
// …Run Code Online (Sandbox Code Playgroud) 我创建了这个小助手来暴露resolve和reject在 Promise 的构造函数之外
export function createPromise() {
let resolve,reject;
let promise = new Promise((r,j) => {
resolve = r;
reject = j;
});
Object.assign(promise,{resolve,reject});
return promise;
}
Run Code Online (Sandbox Code Playgroud)
因为有时将整个脚本包装起来真的很尴尬
new Promise((resolve,reject) => {
// hundreds of lines of code, most which have nothing
// to do with this Promise but I need the Promise object
// at the top level somewhere so that I can expose it,
// but it won't be resolved until some deeply nested …Run Code Online (Sandbox Code Playgroud) 如果没有 jQuery,我将如何编写以下内容?
var dfd = $.Deferred()
dfd.done(done)
dfd.resolve()
function done() {
console.log('done')
}Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>Run Code Online (Sandbox Code Playgroud)
javascript ×6
promise ×5
es6-promise ×3
deferred ×2
asynchronous ×1
ecmascript-6 ×1
jquery ×1
w3c ×1