我有两个指令,每个指令使用包含$ q/$ http调用的同一个工厂.
angular.module("demo").directive("itemA", ["restService", function(restService) {
return {
restrict: "A",
link: function(scope, element, attrs) {
restService.get().then(function(response) {
// whatever
}, function(response) {
// whatever
});
}
};
}]);
angular.module("demo").directive("itemB", ["restService", function(restService) {
return {
restrict: "A",
link: function(scope, element, attrs) {
restService.get().then(function(response) {
// whatever
}, function(response) {
// whatever
});
}
};
}]);
angular.module("demo").factory("restService", ["$http", "$q", function($http, $q) {
return {
get: function() {
var dfd = $q.defer();
$http.get("whatever.json", {
cache: true
}).success(function(response) {
// do some stuff …Run Code Online (Sandbox Code Playgroud) 是否存在同步承诺这样的概念?使用promises语法编写同步代码会有什么好处吗?
try {
foo();
bar(a, b);
bam();
} catch(e) {
handleError(e);
}
Run Code Online (Sandbox Code Playgroud)
...可以写成(但使用同步版本then);
foo()
.then(bar.bind(a, b))
.then(bam)
.fail(handleError)
Run Code Online (Sandbox Code Playgroud) 这是有问题的代码:
new Promise((resolve, reject) => {
const opts = {
credentials: 'same-origin',
};
fetch(`/_api/myAPI`, opts)
.then((res) => {
if (!res.ok) {
reject(res);
} else {
...
Run Code Online (Sandbox Code Playgroud)
如果url抛出异常401,则执行到达reject(res);时抛出Uncaught (in promise)
即使我.catch在.then通话后添加了一个,即
fetch(`/_api/myAPI`, opts)
.then((res) => {
if (!res.ok) {
reject(res);
} else {
...
})
.catch((e) => {
console.log(e);
}
Run Code Online (Sandbox Code Playgroud)
它仍然发生.
为什么reject会抛出此异常,我该如何解决?我的经验仅限于 jQuery.Promise,我不会reject在故障处理程序中触发此错误.
阅读我在 ES6 中理解的文档的含义:
foo => someFun(foo);
Run Code Online (Sandbox Code Playgroud)
相当于:
foo => { return someFun(foo); }
Run Code Online (Sandbox Code Playgroud)
我正在返回一个新的 Promise 并在该代码中使用箭头函数调用解析和拒绝方法,例如
return new Promise(function(resolve, reject)
{
someFunThatReturnsAPromise()
.then(data => resolve(data))
.catch(err => reject(err));
});
Run Code Online (Sandbox Code Playgroud)
因此实际上是当时的代码,
.then(data => return resolve(data))
Run Code Online (Sandbox Code Playgroud)
如果是这样,解析的结果(我不确定值的类型)是否重要,我是否应该稍微简洁一些并使用 {} 编写它以防止隐式返回
.then(data => { resolve(data); })
Run Code Online (Sandbox Code Playgroud) 代码:js:
angular.module('starter.services', ['ngResource'])
.factory('GetMainMenu',['$http','$q','$cacheFactory',function($http,$q,$cacheFactory) {
var methodStr = 'JSONP';
var urlStr = 'http://localhost/bd/wp-admin/admin-ajax.php';
var ptStr = {action:'bd_get_main_menus',callback:'JSON_CALLBACK'};
return {
getMainMenuItems: function(){
var deferred = $q.defer();
$http.jsonp(urlStr,{params: ptStr})
.success(function (data, status) {
deferred.resolve(data);
return deferred.promise;
})
.error(function (data, status) {
deferred.reject(data);
return deferred.promise;
});
}
}
}])
angular.module('starter.controllers', [])
.controller('AppCtrl', function($scope, $ionicModal, $timeout, $http,GetMainMenu) {
GetMainMenu.getMainMenuItems().then(
function(data){
$scope.mainMenus = data;
});
});
Run Code Online (Sandbox Code Playgroud)
运行结果:
TypeError:无法在调用时读取未定义的属性'then'(ht .../www/js/controllers.js:42:33)(ht .../www/lib/ionic/js/ionic.bundle. JS:11994:17)...
这些代码哪里错了?
我希望履行一些其他承诺的承诺.关键是我真的希望在第一个承诺完成后立即获得(仍在等待的)第二个承诺.不幸的是,一旦两个承诺都得到满足,我似乎只能获得第二个承诺的分辨率值.
这是我想到的用例:
var picker = pickFile();
picker.then( // Wait for the user to pick a file.
function(downloadProgress) {
// The user picked a file. The file may not be available just yet (e.g.,
// if it has to be downloaded over the network) but we can already ask
// the user some more questions while the file is being obtained in the
// background.
...do some more user interaction...
return downloadProgress;
}
).then( // Wait for the download …Run Code Online (Sandbox Code Playgroud) 我正在使用一个节点库,它允许发出简单的 http 请求并返回一个承诺 - 这很好用,因为它允许并行创建多个请求,然后我稍后使用Promise.all(). 但是,http 请求只返回一个字符串,我需要知道有关每个请求的一些额外标识信息。所以我认为这样做的一种方法是从请求承诺中链接一些东西并将该信息添加进去。 这是我到目前为止的代码,显示了一个这样的请求被添加到我稍后将收集的承诺数组中:
var promises = [];
promises.push(new Promise(function(resolve, reject){
ReqPromise('http://some.domain.com/getresult.php')
.then(function(reqResult) {
resolve({
source: 'identifier',
value: reqResult
});
});
}));
Run Code Online (Sandbox Code Playgroud)
这就是我在解决这个承诺时得到的回报:
{
source: 'identifier'
value: 1.2.3.4
}
Run Code Online (Sandbox Code Playgroud)
这是“标记”承诺结果的理想方式吗?或者我对承诺有什么误解,这意味着我不需要像上面那样创建额外的承诺?请注意,这ReqPromise是在一个外部库中,因此很难让它接受额外的参数并返回它们。
问题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) 我有承诺的以下功能:
const ajaxRequest = (url) => {
return new Promise(function(resolve, reject) {
axios.get(url)
.then((response) => {
//console.log(response);
resolve(response);
})
.catch((error) => {
//console.log(error);
reject();
});
});
}
const xmlParser = (xml) => {
let { data } = xml;
return new Promise(function(resolve, reject) {
let parser = new DOMParser();
let xmlDoc = parser.parseFromString(data,"text/xml");
if (xmlDoc.getElementsByTagName("AdTitle").length > 0) {
let string = xmlDoc.getElementsByTagName("AdTitle")[0].childNodes[0].nodeValue;
resolve(string);
} else {
reject();
}
});
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试为JSON数组中的每个对象应用这些函数:
const array = [{"id": 1, "url": "www.link1.com"}, {"id": 1, …Run Code Online (Sandbox Code Playgroud) 我正在使用浏览器的本机提取API来处理网络请求.此外,我正在使用whatwg-fetch polyfill用于不支持的浏览器.
但是,如果请求失败,我需要重试.现在我找到了这个npm包whatwg-fetch-retry,但他们没有解释如何在他们的文档中使用它.有人可以帮我这个或建议我另类吗?
javascript ×10
ecmascript-6 ×4
promise ×4
es6-promise ×3
angularjs ×2
asynchronous ×1
deferred ×1
fetch-api ×1
http ×1
ionic ×1
polyfills ×1
q ×1
scope ×1