将 Promise Chaining 从 AngularJs 移植到 VueJs
Porting Promise Chaining from AngularJs to VueJs
与我的上一个问题类似,但差异很大,让我不知所措。我在 AngularJs 中有以下函数,我需要在 VueJs 中重新创建。我有两种类似的方式尝试在 VueJs 中编写此代码,但它们两种方式都会导致大量站点异常。
AngularJs
var foo = function(obj, config) {
if (config.skip) {
return $q.reject("Skipping");
}
var deferred = $q.defer();
obj.promise = deferred.promise;
if (obj.hasValue()) {
deferred.resolve(obj);
} else {
"/api/callToApi".$promise.then(function(res) {
if (res) {
deferred.resolve(res);
else {
deferred.reject(res);
}
});
}
return deferred.promise;
}
VueJs - 取 1。我很确定这个缺少实际的承诺链,不确定如何正确设置它。
var foo = function(obj, config) {
let returnEarly = false;
let promise = new Promise((resolve, reject) => {
returnEarly = true;
reject("Skipping"):
}
if (returnEarly) {
return promise;
}
obj.promise = promise;
return new Promise((resolve, reject) => {
if (obj.hasValue()) {
resolve(obj);
} else {
axios.get("/api/callToApi").then(function(res) {
if (res) {
resolve(res);
} else {
reject(res);
}
}
}
}
}
Take 1 的控制台错误
Uncaught (in promise) Error: Request failed with status code 404
at XMLHttpRequest.__capture__.onreadystatechange
VueJs - 采取 2。我认为这种方式会 return 正确的链接,但是当 运行 开玩笑测试时我得到一个错误 Timeout - Async callback was not invoked within the 5000ms timeout
。
var foo = function(obj, config) {
let returnEarly = false;
let promise = new Promise((resolve, reject) => {
returnEarly = true;
reject("Skipping"):
}
if (returnEarly) {
return promise;
}
obj.promise = promise;
return promise.then(() => {
return new Promise((resolve, reject) => {
if (obj.hasValue()) {
resolve(obj);
} else {
axios.get("/api/callToApi").then(function(res) {
if (res) {
resolve(res);
} else {
reject(res);
}
}
}
}
}
}
这很简单 JavaScript,不特定于 Vue。
一般不需要给obj.promise
分配一个promise,因为它是从函数返回的。
过度使用 new Promise
被称为 promise 构造函数反模式。如果已经有一个 promise(Axios returns 一个),就没有必要创建一个新的,这会导致冗余和容易出错的代码(这可能是 Async callback was not invoked...
错误的原因)。如果需要创建新的承诺,可以使用快捷方式 Promise
方法。
应该是这样的:
function(obj, config) {
if (config.skip) {
return Promise.reject("Skipping");
}
if (obj.hasValue()) {
return Promise.resolve(obj);
} else {
return axios("/api/callToApi").then(function(res) {
if (res)
return res;
else
throw res;
}
});
}
}
一般来说,除了 Error
object 之外的任何错误都是不好的做法。
还要注意 Axios 响应对象总是真实的,可能需要 res.data
。
写成async..await
会更简洁。
与我的上一个问题类似,但差异很大,让我不知所措。我在 AngularJs 中有以下函数,我需要在 VueJs 中重新创建。我有两种类似的方式尝试在 VueJs 中编写此代码,但它们两种方式都会导致大量站点异常。
AngularJs
var foo = function(obj, config) {
if (config.skip) {
return $q.reject("Skipping");
}
var deferred = $q.defer();
obj.promise = deferred.promise;
if (obj.hasValue()) {
deferred.resolve(obj);
} else {
"/api/callToApi".$promise.then(function(res) {
if (res) {
deferred.resolve(res);
else {
deferred.reject(res);
}
});
}
return deferred.promise;
}
VueJs - 取 1。我很确定这个缺少实际的承诺链,不确定如何正确设置它。
var foo = function(obj, config) {
let returnEarly = false;
let promise = new Promise((resolve, reject) => {
returnEarly = true;
reject("Skipping"):
}
if (returnEarly) {
return promise;
}
obj.promise = promise;
return new Promise((resolve, reject) => {
if (obj.hasValue()) {
resolve(obj);
} else {
axios.get("/api/callToApi").then(function(res) {
if (res) {
resolve(res);
} else {
reject(res);
}
}
}
}
}
Take 1 的控制台错误
Uncaught (in promise) Error: Request failed with status code 404
at XMLHttpRequest.__capture__.onreadystatechange
VueJs - 采取 2。我认为这种方式会 return 正确的链接,但是当 运行 开玩笑测试时我得到一个错误 Timeout - Async callback was not invoked within the 5000ms timeout
。
var foo = function(obj, config) {
let returnEarly = false;
let promise = new Promise((resolve, reject) => {
returnEarly = true;
reject("Skipping"):
}
if (returnEarly) {
return promise;
}
obj.promise = promise;
return promise.then(() => {
return new Promise((resolve, reject) => {
if (obj.hasValue()) {
resolve(obj);
} else {
axios.get("/api/callToApi").then(function(res) {
if (res) {
resolve(res);
} else {
reject(res);
}
}
}
}
}
}
这很简单 JavaScript,不特定于 Vue。
一般不需要给obj.promise
分配一个promise,因为它是从函数返回的。
过度使用 new Promise
被称为 promise 构造函数反模式。如果已经有一个 promise(Axios returns 一个),就没有必要创建一个新的,这会导致冗余和容易出错的代码(这可能是 Async callback was not invoked...
错误的原因)。如果需要创建新的承诺,可以使用快捷方式 Promise
方法。
应该是这样的:
function(obj, config) {
if (config.skip) {
return Promise.reject("Skipping");
}
if (obj.hasValue()) {
return Promise.resolve(obj);
} else {
return axios("/api/callToApi").then(function(res) {
if (res)
return res;
else
throw res;
}
});
}
}
一般来说,除了 Error
object 之外的任何错误都是不好的做法。
还要注意 Axios 响应对象总是真实的,可能需要 res.data
。
写成async..await
会更简洁。