打字稿中的复合承诺/Javascript?
Compound Promises in Typescript / Javascript?
我正在编写一个基于 Angular2 的移动应用程序,将 Typescript 与 Nativescript 运行时一起使用,但我遇到了一些 Promises 问题。我有一个 HomeComponent,我希望能够从中调用各种蓝牙功能。这些需要人工交互(如选择设备)和蓝牙扫描的等待时间,因此需要几秒钟才能完成。
我想将这些方法抽象为 promises,所以我这样做了:
HomeComponent.ts:
bluetoothAdd() {
this.isScanning = true;
this._ble.scan().then(
// Log the fulfillment value
function (val) {
this.isScanning = false; //hide activity indicator
this.Connect(this.ble._peripheral);
})
.catch(
function (reason) {
this.isScanning = false; //hide activity indicator
console.log('Handle rejected promise (' + reason + ') here.');
});
}
BluetoothUtils.ts(这是在上面作为 this._ble 导入的):
var devices: Array<string>;
var _peripheral: any;
export function scan() {
return new Promise((resolve, reject) => {
bluetooth.hasCoarseLocationPermission().then(
(granted) => {
if (!granted) {
bluetooth.requestCoarseLocationPermission();
} else {
bluetooth.startScanning({
serviceUUIDs: ["133d"],
seconds: 4,
onDiscovered: (peripheral) => {
console.log("Periperhal found with UUID: " + peripheral.UUID);
}
}).then(() => {
console.log("scanning complete");
}, (err) => {
console.log("error while scanning: " + err);
});
}
});
});
}
使用调试器单步执行我的应用程序后,当在我的 HomeComponent 中调用 bluetoothAdd()
时,我在 BluetoothUtils 中的 scan()
函数按预期工作,并且一种情况,执行 console.log("error while scanning: " + err);
行,说:
error while scanning: Bluetooth is not enabled
但是,HomeComponent this._ble.scan()
承诺的 then
或 catch
部分都没有执行?为什么是这样?你能像我想做的那样复合承诺(即承诺中的承诺)吗?或者有什么想法可以进一步调试吗?
看起来第一个中的代码没有 return 任何内容,即您没有 return 承诺。我希望看到像 return bluetooth.startScanning(..) 这样的东西。您当然可以嵌套承诺,但将它们链接起来更具可读性。 IE。将 console.log 的 then 移动到与前一个 then 相同的嵌套级别。
有一些问题。
1/ 您正在使用 anti pattern。无需在 scan
中创建新的承诺,因为您正在处理的只是承诺。
2/a) 如果你想使用反模式,你需要调用 resolve
和 reject
函数,即在当前情况下,新的承诺永远不会被解决或拒绝,因此 scan
中的 "main" 承诺也从未得到解决或拒绝。
2/b) 更好的解决方案:简单地 return 已经创建的承诺。如果您不这样做 return,它们将成为单独的 promise 分支,并且不会影响 scan
中的 "main" promise 分支,即:
export function scan() {
return bluetooth.hasCoarseLocationPermission().then(
(granted) => {
if (!granted) {
return bluetooth.requestCoarseLocationPermission();
} else {
return bluetooth.startScanning({
serviceUUIDs: ["133d"],
seconds: 4,
onDiscovered: (peripheral) => {
console.log("Periperhal found with UUID: " + peripheral.UUID);
}
}).then(() => {
console.log("scanning complete");
}, (err) => {
console.log("error while scanning: " + err);
});
}
});
}
注意添加的 3 个 return
s:一个在 scan
的顶部,然后在 bluetooth.requestCoarseLocationPermission
和 bluetooth.startScanning
之前
如果你想知道还有哪些其他的 Promise 反模式存在,here's a great resource
由于您使用的是打字稿,请不要再等待await/async
。特别是当你有多个承诺时,它会更清楚。
async function bluetoothAdd() {
this.isScanning = true;
try {
const val = await this._ble.scan();
this.Connect(this.ble._peripheral);
} catch (reason) {
console.log('Handle rejected promise (' + reason + ') here.');
}finally{
this.isScanning = false;
}
}
//Bluetoo.....ts
var devices: Array<string>;
var _peripheral: any;
export async function scan() {
const granted = await bluetooth.hasCoarseLocationPermission();
if(!granted){
return bluetooth.requestCoarseLocationPermission();
}else{
try {
const val = await bluetooth.startScanning({
serviceUUIDs: ["133d"],
seconds: 4,
onDiscovered: (peripheral) => {
console.log("Periperhal found with UUID: " + peripheral.UUID);
}
});
console.log("scanning complete");
return val;
} catch (err) {
// you can rethrow err here such that user `bluetoothAdd` will recieve it/
console.log("error while scanning: " + err);
}
}
}
我正在编写一个基于 Angular2 的移动应用程序,将 Typescript 与 Nativescript 运行时一起使用,但我遇到了一些 Promises 问题。我有一个 HomeComponent,我希望能够从中调用各种蓝牙功能。这些需要人工交互(如选择设备)和蓝牙扫描的等待时间,因此需要几秒钟才能完成。
我想将这些方法抽象为 promises,所以我这样做了:
HomeComponent.ts:
bluetoothAdd() {
this.isScanning = true;
this._ble.scan().then(
// Log the fulfillment value
function (val) {
this.isScanning = false; //hide activity indicator
this.Connect(this.ble._peripheral);
})
.catch(
function (reason) {
this.isScanning = false; //hide activity indicator
console.log('Handle rejected promise (' + reason + ') here.');
});
}
BluetoothUtils.ts(这是在上面作为 this._ble 导入的):
var devices: Array<string>;
var _peripheral: any;
export function scan() {
return new Promise((resolve, reject) => {
bluetooth.hasCoarseLocationPermission().then(
(granted) => {
if (!granted) {
bluetooth.requestCoarseLocationPermission();
} else {
bluetooth.startScanning({
serviceUUIDs: ["133d"],
seconds: 4,
onDiscovered: (peripheral) => {
console.log("Periperhal found with UUID: " + peripheral.UUID);
}
}).then(() => {
console.log("scanning complete");
}, (err) => {
console.log("error while scanning: " + err);
});
}
});
});
}
使用调试器单步执行我的应用程序后,当在我的 HomeComponent 中调用 bluetoothAdd()
时,我在 BluetoothUtils 中的 scan()
函数按预期工作,并且一种情况,执行 console.log("error while scanning: " + err);
行,说:
error while scanning: Bluetooth is not enabled
但是,HomeComponent this._ble.scan()
承诺的 then
或 catch
部分都没有执行?为什么是这样?你能像我想做的那样复合承诺(即承诺中的承诺)吗?或者有什么想法可以进一步调试吗?
看起来第一个中的代码没有 return 任何内容,即您没有 return 承诺。我希望看到像 return bluetooth.startScanning(..) 这样的东西。您当然可以嵌套承诺,但将它们链接起来更具可读性。 IE。将 console.log 的 then 移动到与前一个 then 相同的嵌套级别。
有一些问题。
1/ 您正在使用 anti pattern。无需在 scan
中创建新的承诺,因为您正在处理的只是承诺。
2/a) 如果你想使用反模式,你需要调用 resolve
和 reject
函数,即在当前情况下,新的承诺永远不会被解决或拒绝,因此 scan
中的 "main" 承诺也从未得到解决或拒绝。
2/b) 更好的解决方案:简单地 return 已经创建的承诺。如果您不这样做 return,它们将成为单独的 promise 分支,并且不会影响 scan
中的 "main" promise 分支,即:
export function scan() {
return bluetooth.hasCoarseLocationPermission().then(
(granted) => {
if (!granted) {
return bluetooth.requestCoarseLocationPermission();
} else {
return bluetooth.startScanning({
serviceUUIDs: ["133d"],
seconds: 4,
onDiscovered: (peripheral) => {
console.log("Periperhal found with UUID: " + peripheral.UUID);
}
}).then(() => {
console.log("scanning complete");
}, (err) => {
console.log("error while scanning: " + err);
});
}
});
}
注意添加的 3 个 return
s:一个在 scan
的顶部,然后在 bluetooth.requestCoarseLocationPermission
和 bluetooth.startScanning
如果你想知道还有哪些其他的 Promise 反模式存在,here's a great resource
由于您使用的是打字稿,请不要再等待await/async
。特别是当你有多个承诺时,它会更清楚。
async function bluetoothAdd() {
this.isScanning = true;
try {
const val = await this._ble.scan();
this.Connect(this.ble._peripheral);
} catch (reason) {
console.log('Handle rejected promise (' + reason + ') here.');
}finally{
this.isScanning = false;
}
}
//Bluetoo.....ts
var devices: Array<string>;
var _peripheral: any;
export async function scan() {
const granted = await bluetooth.hasCoarseLocationPermission();
if(!granted){
return bluetooth.requestCoarseLocationPermission();
}else{
try {
const val = await bluetooth.startScanning({
serviceUUIDs: ["133d"],
seconds: 4,
onDiscovered: (peripheral) => {
console.log("Periperhal found with UUID: " + peripheral.UUID);
}
});
console.log("scanning complete");
return val;
} catch (err) {
// you can rethrow err here such that user `bluetoothAdd` will recieve it/
console.log("error while scanning: " + err);
}
}
}