javascript - Typescript/Javascript 中的复合 Promise?

标签 javascript typescript angular promise nativescript

我正在编写一个基于 Angular2 的移动应用程序,使用 Typescript 和 Nativescript 运行时,但面临一些 Promises 问题。我有一个 HomeComponent,我希望能够从中调用各种蓝牙功能。这些需要人工交互(例如选择设备)并等待蓝牙扫描,因此需要几秒钟才能完成。

我想将这些方法抽象为 promise ,所以我这样做了:

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 Scan: "+ err); 行,说:

error while scanning: Bluetooth is not enabled

但是,HomeComponent this._ble.scan() Promise 的 thencatch 部分都没有被执行?为什么是这样?你能像我想做的那样复合 promise (即 promise 中的 promise )吗?或任何想法如何进一步调试?

最佳答案

有一些问题。

1/您正在使用 anti pattern 。无需在 scan 中创建新的 Promise,因为您处理的只是 Promise。

2/a) 如果你想使用反模式,你需要调用 resolvereject 函数,即在当前情况下,新的 Promise 永远不会解决或拒绝,因此 scan 中的“主要” promise 也永远不会解决或拒绝。

2/b) 更好的解决方案:简单地返回已经创建的 promise 。如果您不返回,它们将成为单独的 Promise 分支,并且不会影响 scan 中的“主”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:一个位于 scan 顶部,然后位于 bluetooth.requestCoarseLocationPermissionbluetooth.startScanning 之前

如果您想知道还存在哪些其他 promise 反模式,here's a great resource

关于javascript - Typescript/Javascript 中的复合 Promise?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37498991/

相关文章:

Angular 2中的 Angular Testing 技术Jasmine vs karma vs protractor?

javascript - 如何使用 d3 从 JSON 数组元素渲染表格

javascript - 由于 JS 月间隔 0-11 导致的图表日期错误

javascript - Angular 6 : ERROR TypeError: el. toLowerCase 不是函数

reactjs - React TS 通用组件将通用 Prop 传递给 child

Angular 2延迟加载重定向到空白页面

javascript - 单选按钮填充颜色

javascript - 即 10 : dragstart event doesn't get fired if <img> is wrapped by <a>

Angular ngFor 使用 map

angular - jasmine-karma 中的模块 'undefined' 导入了意外值 'DynamicTestModule'